11.Scanners

扫描仪
相关链接:
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/Scanners.html#//apple_ref/doc/uid/20000147-BCIEFGHC

An NSScanner object scans the characters of an NSString object, typically interpreting the characters and converting them into number and string values. You assign the scanner’s string on creation, and the scanner progresses through the characters of that string from beginning to end as you request items.

  • “NSScanner”对象扫描“NSString”对象的字符,通常解释字符并将它们转换为数字和字符串值。 您在创建时分配扫描仪的字符串,并且当您请求项目时,扫描程序将从头到尾逐步显示该字符串的字符。

Creating a Scanner

NSScanner is a class cluster with a single public class, NSScanner. Generally, you instantiate a scanner object by invoking the class method scannerWithString: or localizedScannerWithString:. Either method returns a scanner object initialized with the string you pass to it. The newly created scanner starts at the beginning of its string. You scan components using the scan... methods such as scanInt:, scanDouble:, and scanString:intoString:. If you are scanning multiple lines, you typically create a while loop that continues until the scanner is at the end of the string, as illustrated in the following code fragment:

  • NSScanner是一个具有单个公共类NSScanner的类集群。 通常,您通过调用类方法scannerWithString:或localizedScannerWithString:来实例化扫描程序对象。 这两种方法都返回一个扫描程序对象,该对象是使用传递给它的字符串初始化 新创建的扫描程序从其字符串的开头开始。 您可以使用scan ...方法扫描组件,例如scanInt:,scanDouble:和scanString:intoString:。 如果要扫描多行,通常会创建一个while循环,直到扫描程序位于字符串的末尾,如下面的代码片段所示:
float aFloat;
NSScanner *theScanner = [NSScanner scannerWithString:aString];
while ([theScanner isAtEnd] == NO) {
 
    [theScanner scanFloat:&aFloat];
    // implementation continues...
}

You can configure a scanner to consider or ignore case using the setCaseSensitive: method. By default a scanner ignores case.

  • 您可以使用setCaseSensitive:方法将扫描程序配置为考虑或忽略大小写。 默认情况下,扫描程序忽略大小写。

Using a Scanner

Scan operations start at the scan location and advance the scanner to just past the last character in the scanned value representation (if any). For example, after scanning an integer from the string “137 small cases of bananas”, a scanner’s location will be 3, indicating the space immediately after the number. Often you need to advance the scan location to skip characters in which you are not interested. You can change the implicit scan location with the setScanLocation: method to skip ahead a certain number of characters (you can also use the method to rescan a portion of the string after an error). Typically, however, you either want to skip characters from a particular character set, scan past a specific string, or scan up to a specific string.

  • 扫描操作从扫描位置开始,并使扫描仪前进到扫描值表示中的最后一个字符(如果有)。 例如,在扫描字符串“137个小香蕉盒”中的整数后,扫描仪的位置将为3,表示该数字后面的空格。 通常,您需要提前扫描位置以跳过您不感兴趣的字符。 您可以使用setScanLocation:方法更改隐式扫描位置以向前跳过一定数量的字符(您也可以使用该方法在发生错误后重新扫描字符串的一部分)。 但是,通常,您要么跳过特定字符集中的字符,扫描特定字符串,要么扫描到特定字符串。

You can configure a scanner to skip a set of characters with the setCharactersToBeSkipped: method. A scanner ignores characters to be skipped at the beginning of any scan operation. Once it finds a scannable character, however, it includes all characters matching the request. Scanners skip whitespace and newline characters by default. Note that case is always considered with regard to characters to be skipped. To skip all English vowels, for example, you must set the characters to be skipped to those in the string “AEIOUaeiou”.

  • 您可以使用setCharactersToBeSkipped:方法将扫描程序配置为跳过一组字符。 扫描程序忽略在任何扫描操作开始时要跳过的字符。 但是,一旦找到可扫描的字符,它就会包含与请求匹配的所有字符。 默认情况下,扫描程序会跳过空格和换行符。 请注意,始终考虑关于要跳过的字符的大小写。 例如,要跳过所有英语元音,必须将要跳过的字符设置为字符串“AEIOUaeiou”中的字符。

If you want to read content from the current location up to a particular string, you can use scanUpToString:intoString: (you can pass NULL as the second argument if you simply want to skip the intervening characters). For example, given the following string:

  • 如果要从当前位置读取内容到特定字符串,可以使用scanUpToString:intoString :(如果您只想跳过插入的字符,则可以将NULL作为第二个参数传递)。 例如,给定以下字符串:
137 small cases of bananas

you can find the type of container and number of containers using scanUpToString:intoString: as shown in the following example.

  • 您可以使用scanUpToString:intoString找到容器类型和容器数量:如以下示例所示。
NSString *bananas = @"137 small cases of bananas";
NSString *separatorString = @" of";
 
NSScanner *aScanner = [NSScanner scannerWithString:bananas];
 
NSInteger anInteger;
[aScanner scanInteger:&anInteger];
NSString *container;
[aScanner scanUpToString:separatorString intoString:&container];

It is important to note that the search string (separatorString) is " of". By default a scanner ignores whitespace, so the space character after the integer is ignored. Once the scanner begins to accumulate characters, however, all characters are added to the output string until the search string is reached. Thus if the search string is "of" (no space before), the first value of container is “small cases ” (includes the space following); if the search string is " of" (with a space before), the first value of container is “small cases” (no space following).

  • 重要的是要注意搜索字符串(separatorString)是“of”。 默认情况下,扫描程序会忽略空格,因此忽略整数后的空格字符。 但是,一旦扫描程序开始累积字符,所有字符都将添加到输出字符串,直到到达搜索字符串。 因此,如果搜索字符串是“of”(之前没有空格),则容器的第一个值是“小情况”(包括后面的空格); 如果搜索字符串是“of”(前面有空格),则容器的第一个值是“small cases”(后面没有空格)。

After scanning up to a given string, the scan location is the beginning of that string. If you want to scan past that string, you must therefore first scan in the string you scanned up to. The following code fragment illustrates how to skip past the search string in the previous example and determine the type of product in the container. Note the use of substringFromIndex: to in effect scan up to the end of a string.

  • 扫描到给定字符串后,扫描位置是该字符串的开头。 如果要扫描该字符串,则必须先扫描最近扫描的字符串。 以下代码片段说明了如何跳过前一个示例中的搜索字符串并确定容器中的产品类型。 注意使用substringFromIndex:实际上扫描到字符串的结尾。
[aScanner scanString:separatorString intoString:NULL];
NSString *product;
product = [[aScanner string] substringFromIndex:[aScanner scanLocation]];
// could also use:
// product = [bananas substringFromIndex:[aScanner scanLocation]];

Example

Suppose you have a string containing lines such as:

  • 假设您有一个包含以下行的字符串:
  • Product: Acme Potato Peeler; Cost: 0.98 73

    • 产品:Acme土豆去皮机; 费用:0.98 73
  • Product: Chef Pierre Pasta Fork; Cost: 0.75 19

    • 产品:厨师Pierre Pasta Fork; 费用:0.75 19
  • Product: Chef Pierre Colander; Cost: 1.27 2

    • 产品:厨师Pierre Colander; 费用:1.27 2

The following example uses alternating scan operations to extract the product names and costs (costs are read as a float for simplicity’s sake), skipping the expected substrings “Product:” and “Cost:”, as well as the semicolon. Note that because a scanner skips whitespace and newlines by default, the loop does no special processing for them (in particular there is no need to do additional whitespace processing to retrieve the final integer).

  • 以下示例使用交替扫描操作来提取产品名称和成本(为简单起见,成本读取为浮点数),跳过预期的子串“Product:”和“Cost:”,以及分号。 请注意,由于扫描程序默认情况下会跳过空格和换行符,因此循环不对它们进行特殊处理(特别是不需要执行额外的空格处理来检索最终整数)。
NSString *string = @"Product: Acme Potato Peeler; Cost: 0.98 73\n\
Product: Chef Pierre Pasta Fork; Cost: 0.75 19\n\
Product: Chef Pierre Colander; Cost: 1.27 2\n";
 
NSCharacterSet *semicolonSet;
NSScanner *theScanner;
 
NSString *PRODUCT = @"Product:";
NSString *COST = @"Cost:";
 
NSString *productName;
float productCost;
NSInteger productSold;
 
semicolonSet = [NSCharacterSet characterSetWithCharactersInString:@";"];
theScanner = [NSScanner scannerWithString:string];
 
while ([theScanner isAtEnd] == NO)
{
    if ([theScanner scanString:PRODUCT intoString:NULL] &&
        [theScanner scanUpToCharactersFromSet:semicolonSet
            intoString:&productName] &&
        [theScanner scanString:@";" intoString:NULL] &&
        [theScanner scanString:COST intoString:NULL] &&
        [theScanner scanFloat:&productCost] &&
        [theScanner scanInteger:&productSold])
    {
        NSLog(@"Sales of %@: $%1.2f", productName, productCost * productSold);
    }
}

Localization

A scanner bases some of its scanning behavior on a locale, which specifies a language and conventions for value representations. NSScanner uses only the locale’s definition for the decimal separator (given by the key named NSDecimalSeparator). You can create a scanner with the user’s locale by using localizedScannerWithString:, or set the locale explicitly using setLocale:. If you use a method that doesn’t specify a locale, the scanner assumes the default locale values.

  • 扫描程序将其某些扫描行为基于区域设置,该区域设置指定值表示的语言和约定。 NSScanner仅使用区域设置的小数分隔符定义(由名为NSDecimalSeparator的键给出)。 您可以使用localizedScannerWithString:创建具有用户区域设置的扫描程序,或使用setLocale:显式设置区域设置。 如果使用未指定语言环境的方法,则扫描程序将采用默认语言环境值。

你可能感兴趣的:(11.Scanners)