Mam NSString (numer telefonu) z nawiasami i łącznikami, ponieważ niektóre numery telefonów są sformatowane. Jak usunąć wszystkie znaki z wyjątkiem liczb z ciągu?
objective-c
nsstring
Ben Harris
źródło
źródło
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"charactersGoHere"]
NSString *pureNumbers = [pureNumbers stringByTrimmingCharactersInSet: [NSCharacterSet decimalDigitCharacterSet] invertedSet]
nie działa?[NSCharacterSet decimalDigitCharacterSet]
inny, który zawiera tylko cyfry i litery. Można skonstruować jedną poprzez tworzenieNSMutableCharaterSet
i przechodzącejdecimalDigitCharacterSet
,uppercaseLetterCharacterSet
alowercaseLetterCharacterSet
doformUnionWithCharacterSet:
. Zauważ, żeletterCharacterSet
obejmuje to również znaki, stąd użycie małych i wielkich liter.Nie ma potrzeby używania biblioteki wyrażeń regularnych, jak sugerują inne odpowiedzi - wywoływana jest klasa, której szukasz
NSScanner
. Jest używany w następujący sposób:EDYTOWAĆ: Zaktualizowałem kod, ponieważ oryginał został spisany na czubku mojej głowy i pomyślałem, że wystarczy, aby skierować ludzi we właściwym kierunku. Wygląda na to, że ludzie szukają kodu, który mogą po prostu skopiować i wkleić bezpośrednio do swojej aplikacji.
Zgadzam się również, że rozwiązanie Michaela Pelz-Shermana jest bardziej odpowiednie niż używanie
NSScanner
, więc warto się temu przyjrzeć.źródło
Zaakceptowana odpowiedź jest przesada, jeśli chodzi o to, o co się pytamy. To jest znacznie prostsze:
źródło
To świetnie, ale kod nie działa dla mnie na iPhone 3.0 SDK.
Jeśli zdefiniuję strippedString, tak jak tutaj pokazujesz, pojawia się,
BAD ACCESS error
gdy próbuję go wydrukować poscanCharactersFromSet:intoString
wywołaniu.Jeśli tak robię:
W końcu otrzymuję pusty ciąg, ale kod nie ulega awarii.
Zamiast tego musiałem uciec się do starego, dobrego C:
źródło
Chociaż jest to stare pytanie z działającymi odpowiedziami, brakowało mi obsługi formatu międzynarodowego . Bazując na rozwiązaniu simonobo, zmieniony zestaw znaków zawiera znak plus „+”. Niniejsza poprawka obsługuje również międzynarodowe numery telefonów.
Wyrażenia Swift są
Co daje +12345671000 jako powszechny międzynarodowy format numeru telefonu.
źródło
Oto wersja Swift tego.
źródło
Szybka wersja najpopularniejszej odpowiedzi:
Edycja: składnia dla języka Swift 2
Edycja: składnia dla języka Swift 3
źródło
Dzięki za przykład. Brakuje tylko jednej rzeczy inkrementacji scanLocation w przypadku, gdy jeden ze znaków w originalString nie zostanie znaleziony wewnątrz obiektu numbers CharacterSet. Dodałem instrukcję else {}, aby to naprawić.
źródło
Akceptuje tylko numer telefonu komórkowego
źródło
Warto zauważyć, że zaakceptowano
componentsSeparatedByCharactersInSet:
icomponentsJoinedByString:
oparta na niej odpowiedź nie jest rozwiązaniem zapewniającym oszczędność pamięci. Alokuje pamięć na zestaw znaków, tablicę i nowy ciąg. Nawet jeśli są to tylko tymczasowe przydziały, przetwarzanie w ten sposób wielu ciągów może szybko zapełnić pamięć.Bardziej przyjaznym dla pamięci podejściem byłoby operowanie na modyfikowalnej kopii łańcucha w miejscu. W kategorii ponad NSString:
Profilowanie tych dwóch podejść pokazało, że zużywa to około 2/3 mniej pamięci.
źródło
Możesz użyć wyrażenia regularnego na zmiennym ciągu:
źródło
Zbudowano najlepsze rozwiązanie jako kategorię, aby pomóc w rozwiązaniu szerszych problemów:
Berło:
Wdrażanie:
Stosowanie:
źródło
Szybki 3
źródło
Swift 4.1
źródło
Um. Pierwsza odpowiedź wydaje mi się całkowicie błędna. NSScanner jest naprawdę przeznaczony do analizowania. W przeciwieństwie do wyrażenia regularnego, pozwala on analizować ciąg po jednym małym kawałku na raz. Inicjalizuje się go łańcuchem i utrzymuje indeks tego, jak daleko w ciągu otrzymano; Ten indeks jest zawsze jego punktem odniesienia, a wszelkie polecenia, które mu wydajesz, odnoszą się do tego punktu. Mówisz mu: „ok, podaj mi następny fragment znaków w tym zestawie” lub „podaj liczbę całkowitą, którą znajdziesz w ciągu znaków”, a te zaczynają się od bieżącego indeksu i idą do przodu, aż znajdą coś, co nie mecz. Jeśli pierwszy znak już nie pasuje, metoda zwraca NIE, a indeks nie zwiększa się.
Kod w pierwszym przykładzie skanuje „(123) 456-7890” w poszukiwaniu znaków dziesiętnych, co już kończy się niepowodzeniem od pierwszego znaku, więc wywołanie scanCharactersFromSet: intoString: pozostawia przekazany strippedString w spokoju i zwraca NO; Kod całkowicie ignoruje sprawdzanie zwracanej wartości, pozostawiając strippedString nieprzypisany. Nawet jeśli pierwszy znak byłby cyfrą, kod nie powiódłby się, ponieważ zwróciłby tylko cyfry, które znajdzie, aż do pierwszego myślnika, parenu lub czegokolwiek.
Jeśli naprawdę chciałeś użyć NSScanner, możesz umieścić coś takiego w pętli i dalej sprawdzać, czy nie zwraca zwracanej wartości NO, a jeśli to otrzymasz, możesz zwiększyć wartość scanLocation i skanować ponownie; musisz też sprawdzić isAtEnd i yada yada yada. Krótko mówiąc, niewłaściwe narzędzie do pracy. Rozwiązanie Michaela jest lepsze.
źródło
Osoby szukające ekstrakcji telefonu mogą wyodrębnić numery telefonów z tekstu za pomocą narzędzia NSDataDetector, na przykład:
`
źródło
Utworzyłem kategorię na NSString, aby uprościć tę typową operację.
NSString + AllowCharactersInSet.h
NSString + AllowCharactersInSet.m
źródło
Myślę, że obecnie najlepszym sposobem jest:
źródło
Jeśli szukasz po prostu chwycić numery od napisu, to mógłby z pewnością używać wyrażeń regularnych do analizowania ich. Aby wykonać regex w Objective-C, sprawdź RegexKit .Edytować: Jak wskazuje @Nathan, użycie NSScanner jest znacznie prostszym sposobem analizowania wszystkich liczb z ciągu. Całkowicie nie byłam świadoma tej opcji, więc dziękuję mu za zasugerowanie tego. (Sam nawet nie lubię używać wyrażeń regularnych, więc wolę podejścia, które ich nie wymagają).Jeśli chcesz sformatować numery telefonów do wyświetlania, warto przyjrzeć się NSNumberFormatter . Proponuję przeczytać to powiązane pytanie SO, aby uzyskać wskazówki, jak to zrobić. Pamiętaj, że numery telefonów mają różny format w zależności od lokalizacji i / lub regionu.
źródło
Szybki 5
źródło
Na podstawie odpowiedzi Jona Vogela jest to rozszerzenie Swift String wraz z kilkoma podstawowymi testami.
I kilka testów potwierdzających przynajmniej podstawową funkcjonalność:
To odpowiada na pytanie OP, ale można je łatwo zmodyfikować, aby pozostawić znaki związane z numerem telefonu, takie jak ",; * # +"
źródło
];
Nie komplikuj!
źródło