Jaka jest najlepsza implementacja czystego Pythona do sprawdzania, czy ciąg zawiera JAKIEKOLWIEK litery alfabetu?
string_1 = "(555).555-5555"
string_2 = "(555) 555 - 5555 ext. 5555
Gdzie string_1
wróciłoby, False
gdyby nie było w nim żadnych liter alfabetu i string_2
wróciłoby, gdyby True
miał literę.
Odpowiedzi:
Regex powinien być szybkim podejściem:
re.search('[a-zA-Z]', the_string)
źródło
any(c.isalpha() for c in string_1)
jest cudownie Pythonic.isalpha
ogóle znaczy? Będzie to miało zupełnie inne zachowanie podczas porównywania Pythona 2 z Pythonem 3. Czy chiński jest częścią alfabetu? Jeśli nie, ślepo dopasowujesz go do swojego generatora w Pythonie 3 (lub Pythonie 2 w przypadku ciągów znaków Unicode!). Jeśli chcesz pythonic , to jest tutaj:Simple is better than complex.
. I sprawdź komentarz OP powyżej: chce, aby dopasowano tylko alfabet łaciński.Match
obiekt, jeśli istnieje dopasowanie lubNone
nie ma. Więc jest to zgodne zeif re.search(...
wzorem.Co powiesz na:
>>> string_1 = "(555).555-5555" >>> string_2 = "(555) 555 - 5555 ext. 5555" >>> any(c.isalpha() for c in string_1) False >>> any(c.isalpha() for c in string_2) True
źródło
set(string_1)
bardziej skuteczny?set
może, ale nie musi, zmniejszyć wywołania funkcji, ale dodaje pewien narzut.Możesz użyć
islower()
na swoim ciągu, aby sprawdzić, czy zawiera małe litery (wśród innych znaków).or
to zisupper()
również sprawdzić, czy zawiera kilka wielkich liter:poniżej: litery w łańcuchu: test daje wartość true
>>> z = "(555) 555 - 5555 ext. 5555" >>> z.isupper() or z.islower() True
poniżej: brak liter w ciągu: test daje fałsz.
>>> z= "(555).555-5555" >>> z.isupper() or z.islower() False >>>
Nie należy mylić z tym,
isalpha()
co powracaTrue
tylko wtedy, gdy wszystkie znaki są literami, co nie jest tym, czego chcesz.Zauważ, że barm za finalizuje odpowiedź kopalni ładnie, ponieważ kopalnia nie obsługuje mieszane sprawę dobrze.
źródło
Podobała mi się odpowiedź udzielona przez @ jean-françois-fabre , ale jest niekompletna.
Jego podejście zadziała, ale tylko wtedy, gdy tekst zawiera wyłącznie małe lub duże litery:
>>> text = "(555).555-5555 extA. 5555" >>> text.islower() False >>> text.isupper() False
Lepszym podejściem jest najpierw wielkie lub małe litery w ciągu, a następnie sprawdzenie.
>>> string1 = "(555).555-5555 extA. 5555" >>> string2 = '555 (234) - 123.32 21' >>> string1.upper().isupper() True >>> string2.upper().isupper() False
źródło
Możesz użyć wyrażenia regularnego w następujący sposób:
import re print re.search('[a-zA-Z]+',string)
źródło
Przetestowałem każdą z powyższych metod, aby dowiedzieć się, czy w danym ciągu znajdują się jakieś alfabety i znalazłem średni czas przetwarzania na ciąg na standardowym komputerze.
~ 250 ns dla
import re
~ 3 µs dla
re.search('[a-zA-Z]', string)
~ 6 µs dla
any(c.isalpha() for c in string)
~ 850 ns dla
W przeciwieństwie do tego, co przypuszczano, importowanie re zajmuje niewiele czasu, a wyszukiwanie za pomocą re zajmuje około połowy czasu w porównaniu z iteracją isalpha () nawet dla stosunkowo małego ciągu.
Dlatego w przypadku większych ciągów i większej liczby zliczeń re byłby znacznie bardziej wydajny.
Ale konwersja ciągu znaków na wielkość liter i sprawdzenie wielkości liter (tj . Dowolna z właściwości upper (). Isupper () lub lower (). Islower () ) wygrywa tutaj. W każdej pętli jest znacznie szybszy niż re.search () i nie wymaga nawet dodatkowego importu.
źródło
Możesz to również zrobić dodatkowo
import re string='24234ww' val = re.search('[a-zA-Z]+',string) val[0].isalpha() # returns True if the variable is an alphabet print(val[0]) # this will print the first instance of the matching value
Zauważ również, że jeśli zmienna val zwraca None. Oznacza to, że wyszukiwanie nie znalazło dopasowania
źródło