Um. Первый ответ кажется мне совершенно неверным. NSScanner действительно предназначен для разбора. В отличие от регулярных выражений, вы разбираете строку по одному крошечному фрагменту за раз. Вы инициализируете его строкой, и он поддерживает индекс того, как далеко вдоль строки он получен; Этот показатель всегда его точка отсчета, и все команды, которые вы даете его по сравнению с этой точкой. Вы говорите: «Хорошо, дайте мне следующий кусок символов в этом наборе» или «Дайте мне целое число, которое вы найдете в строке», и они начинаются с текущего индекса и продвигаются, пока не найдут то, что не матч. Если самый первый символ уже не совпадает, то метод возвращает NO, и индекс не увеличивается.
Код в первом примере сканирует "(123) 456-7890" на наличие десятичных символов, что уже не выполняется с самого первого символа, поэтому вызов scanCharactersFromSet: intoString: оставляет переданную в strippedString одну и возвращает НЕТ; Код полностью игнорирует проверку возвращаемого значения, оставляя strippedString неназначенным. Даже если бы первый символ был цифрой, этот код потерпел бы неудачу, так как он возвращал бы только те цифры, которые он обнаружил, до первой черты или пары, или чего-то еще.
Если вы действительно хотите использовать NSScanner, вы можете поместить что-то подобное в цикл и продолжать проверять возвращаемое значение NO, а если вы его получите, вы можете увеличивать scanLocation и сканировать снова; и вам также нужно проверить isAtEnd и yada yada yada. Короче говоря, неправильный инструмент для работы. Решение Майкла лучше.