Сканеры.

Cocoa

Объект NSScanner сканирует символы объекта NSString, как правило, интерпретируя символы и преобразуя их в числа и строковые значения. Вы назначаете строку сканера при создании, и сканер продвигается по символам этой строки от начала до конца, когда вы запрашиваете элементы.

Создание сканера

NSScanner класс кластер с одним открытым классом, NSScanner. Как правило, вы реализуете объект сканер, вызвав метод класса scannerWithString: или localizedScannerWithString:. Любой метод возвращает объект сканера инициализированный строкой, которую вы передаете ему. Вновь созданный сканер начинается в начале своей строки. Вы сканируете компоненты с помощью scan... методов, таких как scanInt:, scanDouble: и scanString:intoString. При сканировании нескольких строк, как правило, создается цикл while, который продолжается, пока сканер не достигнет конца строки, как показано в следующем фрагменте кода:

float aFloat;

NSScanner *theScanner = [NSScanner scannerWithString:aString];

while ([theScanner isAtEnd] == NO) {
    [theScanner scanFloat:&aFloat];
    // продолжение реализации...
}

Вы можете настроить сканер, чтобы он рассматривал или игнорировал регистр используя метод setCaseSensitive:. По умолчанию сканер не учитывает регистр.

Использование сканера

Операции сканирования начинаются с проверки местонахождения сразу за последним символом в отсканированном участке (если таковой имеется). Например, после сканирования чисел в строке "137 small cases of bananas", расположение сканера будет 3, что указывает на пробел сразу после числа. Часто вам нужно переместить место сканирования, чтобы пропустить символы, в которых вы не заинтересованы. Вы можете изменить начальную точку сканирования с помощью метода setScanLocation:, чтобы пропустить определенное количество символов (вы также можете использовать этот метод для повторного сканирования части строки после ошибки). Обычно, однако, вы либо хотите пропустить символы из определенного набора символов, прошлое сканирование определенной строки, или сканировать до определенного места.

Вы можете настроить сканер, чтобы пропустить набор символов с помощью метода setCharactersToBeSkipped:. Сканер игнорирует символы, которые должны быть пропущены в начале какой-либо операции сканирования. Как только он находит сканируемой символ, он включает в себя все символы, соответствующие запросу. Сканеры пропусткают пробелы и символы новой строки по умолчанию. Обратите внимание, что регистр всегда рассматривается с символами, которые будут пропущены. Чтобы пропустить все английские гласные, вы должны установить символы, которые будут пропущены в строке: "AEIOUaeiou".

Если вы хотите прочитать содержимое текущего местоположения до определенной строки, вы можете использовать scanUpToString:intoString: (Вы можете передать NULL в качестве второго аргумента, если вы просто хотите пропустить промежуточные символы). Например, в следующей строке:


137 small cases of bananas

Вы можете найти тип контейнера и количество контейнеров, используя 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];

Важно отметить, что строка поиска (separatorString) содержит " of". По умолчанию сканер игнорирует пробелы, поэтому пробел после целого игнорируется. Как только сканер начинает накапливать символы, все символы добавляются в выходную строку, пока строка поиска не будет достигнута. Таким образом, если строка поиска "of" (без первого пробела), первое значение container "small cases " (включает в себя последующие пробелы), если строка поиска " of" (с начальным пробелом), то первое значение container "small cases" (без следующего пробела).

После сканирования до заданной строки, расположение сканирования установлено в начале этой строки. Если вы хотите проверить предидущее содержание этой строки, вы должны выполнить первое сканирование в строке, которую Вы просматривали до этого. Следующий фрагмент кода показывает, как можно пропустить мимо строку поиска из предыдущего примера, и определить тип продукта в контейнере. Обратите внимание на использование substringFromIndex: в действие сканирования до конца строки.

[aScanner scanString:separatorString intoString:NULL];
NSString *product;
product = [[aScanner string] substringFromIndex:[aScanner scanLocation]];
// Можно также использовать:
// product = [bananas substringFromIndex:[aScanner scanLocation]];

Пример:

Предположим, у вас есть строка, содержащая подстроки, такие как:

  • Product: Acme Potato Peeler; Cost: 0.98 73
  • Product: Chef Pierre Pasta Fork; Cost: 0.75 19
  • Product: Chef Pierre Colander; Cost: 1.27 2

Следующий пример использует дублирование операций сканирования для извлечения названия продуктов и расходов (расходы, которые читаются как float для простоты), пропуская подстроки "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);
    }
}

Локализация

NSScanner использует только определение локали для десятичного разделителя (выдается ключ NSDecimalSeparator). Вы можете создать сканер с локалью пользователя с помощью localizedScannerWithString: или установить локаль явно с помощью setLocale:. Если вы используете метод, который не определяет язык, сканер принимает значения локали по умолчанию.

 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac