Удалить все, кроме номеров из NSString - PullRequest
157 голосов
/ 15 июля 2009

У меня есть NSString (номер телефона) с некоторыми скобками и дефисами, так как некоторые номера телефонов отформатированы. Как удалить все символы, кроме цифр, из строки?

Ответы [ 22 ]

2 голосов
/ 17 июня 2014

Вы можете использовать регулярное выражение для изменяемой строки:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:
                                @"[^\\d]"
                                options:0
                                error:nil];

[regex replaceMatchesInString:str
                      options:0 
                        range:NSMakeRange(0, str.length) 
                 withTemplate:@""];
1 голос
/ 14 августа 2018

Свифт 4,1

var str = "75003 Paris, France"
var stringWithoutDigit = (str.components(separatedBy:CharacterSet.decimalDigits)).joined(separator: "")
print(stringWithoutDigit)
1 голос
/ 16 ноября 2016

Свифт 3

let notNumberCharacters = NSCharacterSet.decimalDigits.inverted
let intString = yourString.trimmingCharacters(in: notNumberCharacters)
1 голос
/ 04 июля 2013

Создано топовое решение как категория для решения более широких проблем:

Интерфейс:

@interface NSString (easyReplace)
- (NSString *)stringByReplacingCharactersNotInSet:(NSCharacterSet *)set 
                                             with:(NSString *)string;
@end

реализация внешний:

@implementation NSString (easyReplace)
- (NSString *)stringByReplacingCharactersNotInSet:(NSCharacterSet *)set 
                                             with:(NSString *)string
{
    NSMutableString *strippedString = [NSMutableString
                                       stringWithCapacity:self.length];

    NSScanner *scanner = [NSScanner scannerWithString:self];

    while ([scanner isAtEnd] == NO) {
        NSString *buffer;
        if ([scanner scanCharactersFromSet:set intoString:&buffer]) {
            [strippedString appendString:buffer];
        } else {
            [scanner setScanLocation:([scanner scanLocation] + 1)];
            [strippedString appendString:string];
        }
    }
    return [NSString stringWithString:strippedString];
}
@end

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

NSString *strippedString = 
 [originalString stringByReplacingCharactersNotInSet:
   [NSCharacterSet setWithCharactersInString:@"01234567890" 
                                        with:@""];
0 голосов
/ 21 августа 2010
NSString *originalPhoneNumber = @"(123) 123-456 abc";
NSCharacterSet *numbers = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
NSString *trimmedPhoneNumber = [originalPhoneNumber stringByTrimmingCharactersInSet:numbers];

];

Будьте проще!

0 голосов
/ 22 июля 2009

Um. Первый ответ кажется мне совершенно неверным. NSScanner действительно предназначен для разбора. В отличие от регулярных выражений, вы разбираете строку по одному крошечному фрагменту за раз. Вы инициализируете его строкой, и он поддерживает индекс того, как далеко вдоль строки он получен; Этот показатель всегда его точка отсчета, и все команды, которые вы даете его по сравнению с этой точкой. Вы говорите: «Хорошо, дайте мне следующий кусок символов в этом наборе» или «Дайте мне целое число, которое вы найдете в строке», и они начинаются с текущего индекса и продвигаются, пока не найдут то, что не матч. Если самый первый символ уже не совпадает, то метод возвращает NO, и индекс не увеличивается.

Код в первом примере сканирует "(123) 456-7890" на наличие десятичных символов, что уже не выполняется с самого первого символа, поэтому вызов scanCharactersFromSet: intoString: оставляет переданную в strippedString одну и возвращает НЕТ; Код полностью игнорирует проверку возвращаемого значения, оставляя strippedString неназначенным. Даже если бы первый символ был цифрой, этот код потерпел бы неудачу, так как он возвращал бы только те цифры, которые он обнаружил, до первой черты или пары, или чего-то еще.

Если вы действительно хотите использовать NSScanner, вы можете поместить что-то подобное в цикл и продолжать проверять возвращаемое значение NO, а если вы его получите, вы можете увеличивать scanLocation и сканировать снова; и вам также нужно проверить isAtEnd и yada yada yada. Короче говоря, неправильный инструмент для работы. Решение Майкла лучше.

0 голосов
/ 23 апреля 2016

Основываясь на ответе Джона Фогеля, он представляет собой расширение Swift String вместе с некоторыми базовыми тестами.

import Foundation
extension String {
    func stringByRemovingNonNumericCharacters() -> String {
        return self.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
    }
}

И некоторые тесты, подтверждающие хотя бы базовую функциональность:

import XCTest

class StringExtensionTests: XCTestCase {

    func testStringByRemovingNonNumericCharacters() {

        let baseString = "123"
        var testString = baseString
        var newString = testString.stringByRemovingNonNumericCharacters()
        XCTAssertTrue(newString == testString)

        testString = "a123b"
        newString = testString.stringByRemovingNonNumericCharacters()
        XCTAssertTrue(newString == baseString)

        testString = "a=1-2_3@b"
        newString = testString.stringByRemovingNonNumericCharacters()
        XCTAssertTrue(newString == baseString)

        testString = "(999) 999-9999"
        newString = testString.stringByRemovingNonNumericCharacters()
        XCTAssertTrue(newString.characters.count == 10)
        XCTAssertTrue(newString == "9999999999")

        testString = "abc"
        newString = testString.stringByRemovingNonNumericCharacters()
        XCTAssertTrue(newString == "")
    }
}

Это отвечает на вопрос ОП, но его можно легко изменить, чтобы оставить в телефонном номере связанные символы, такие как ",; * # +"

0 голосов
/ 15 апреля 2012

Для тех, кто ищет извлечение телефона, вы можете извлечь телефонные номера из текста, используя NSDataDetector, например:

NSString *userBody = @"This is a text with 30612312232 my phone";
if (userBody != nil) {
    NSError *error = NULL;
    NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber error:&error];
    NSArray *matches = [detector matchesInString:userBody options:0 range:NSMakeRange(0, [userBody length])];
    if (matches != nil) {
        for (NSTextCheckingResult *match in matches) {
            if ([match resultType] == NSTextCheckingTypePhoneNumber) {
                DbgLog(@"Found phone number %@", [match phoneNumber]);
            }
        }
    }
}

`

0 голосов
/ 17 апреля 2017

Я думаю, что в настоящее время лучший способ:

phoneNumber.replacingOccurrences(of: "\\D",
                               with: "",
                            options: String.CompareOptions.regularExpression)
0 голосов
/ 05 сентября 2012

Я создал категорию на NSString, чтобы упростить эту обычную операцию.

NSString + AllowCharactersInSet.h

@interface NSString (AllowCharactersInSet)

- (NSString *)stringByAllowingOnlyCharactersInSet:(NSCharacterSet *)characterSet;

@end

NSString + AllowCharactersInSet.m

@implementation NSString (AllowCharactersInSet)

- (NSString *)stringByAllowingOnlyCharactersInSet:(NSCharacterSet *)characterSet {
    NSMutableString *strippedString = [NSMutableString
                                   stringWithCapacity:self.length];

    NSScanner *scanner = [NSScanner scannerWithString:self];

    while (!scanner.isAtEnd) {
        NSString *buffer = nil;

        if ([scanner scanCharactersFromSet:characterSet intoString:&buffer]) {
            [strippedString appendString:buffer];
        } else {
            scanner.scanLocation = scanner.scanLocation + 1;
        }
    }

    return strippedString;
}

@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...