W artykule Wikipedii na temat wyrażeń regularnych wydaje się, że [[:digit:]]
= [0-9]
= \d
.
W jakich okolicznościach nie są one równe? Jaka jest różnica?
Po niektórych badaniach wydaje mi się, że jedną różnicą jest to, że wyrażenie w [:expr:]
nawiasach zależy od ustawień regionalnych.
regular-expression
wildcards
Harbinn
źródło
źródło
Odpowiedzi:
Tak, jest to
[[:digit:]]
~[0-9]
~\d
(gdzie ~ oznacza przybliżone).W większości języków programowania (tam, gdzie jest obsługiwany)
\d
≡[[:digit:]]
(identyczny). Jest mniej powszechne niż (nie w POSIX ale jest w GNU ).\d
[[:digit:]]
grep -P
W UNICODE jest wiele cyfr , na przykład:
123456789 # Hindu-Arabic
cyfry arabskie٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI
Z których wszystkie mogą być zawarte w
[[:digit:]]
lub\d
.Zamiast tego
[0-9]
generalnie są to tylko cyfry ASCII0123456789
.Istnieje wiele języków: Perl, Java, Python, C. W których
[[:digit:]]
(i\d
) wymaga rozszerzenia znaczenia. Na przykład ten kod perla będzie pasował do wszystkich cyfr z góry:Co jest równoważne z zaznaczeniem wszystkich znaków, które mają właściwości Unicode
Numeric
idigits
:Który grep mógłby się reprodukować (konkretna wersja pcre może mieć inną wewnętrzną listę punktów kodu niż Perl):
Zmień na [0-9], aby zobaczyć:
POSIX
Dla konkretnego POSIX BRE lub ERE:
Nie
\d
jest obsługiwany (nie w POSIX, ale w GNUgrep -P
).[[:digit:]]
jest wymagany przez POSIX, aby odpowiadał cyfrowej klasie znaków, która z kolei jest wymagana przez ISO C jako znaki od 0 do 9 i nic więcej. Tak tylko w C locale wszystko[0-9]
,[0123456789]
,\d
i[[:digit:]]
znaczy dokładnie to samo. Nie[0123456789]
ma żadnych możliwych błędnych interpretacji,[[:digit:]]
jest dostępny w większej liczbie programów narzędziowych i zwykle oznacza tylko[0123456789]
.\d
Jest obsługiwana przez kilku narzędzi.Jeśli chodzi o
[0-9]
znaczenie wyrażeń zakresowych, POSIX definiuje je tylko w ustawieniach regionalnych C. w innych lokalizacjach może być inaczej (może to być kolejność kodów lub kolejność sortowania lub coś innego).muszle
Niektóre implementacje mogą rozumieć zakres jako coś innego niż zwykły porządek ASCII (na przykład ksh93):
I to jest pewne źródło błędów, które czekają na wystąpienie.
źródło
iswctype()
i symbolach BRE / ERE / w narzędziach POSIX, [0-9] i [[: digit:]] pasują tylko do 0123456789. I które będą wyraźnie w następnej wersji standarduperl
jest\d
w trybie Unicode dopasowanym cyframi dziesiętnymi z innych skryptów. Dziękuję za to. W PCRE patrz(*UCP)
jak w GNUgrep -Po '(*UCP)\d'
lubgrep -Po '(*UCP)[[:digit:]]
aby klasy były oparte na właściwościach Unicode.[:digit:]
składnia sugeruje, że chcesz użyć lokalizacji, czyli tego, co użytkownik uważa za cyfrę. Nigdy nie używam,[:digit:]
ponieważ w praktyce jest to to samo, co[0-9]
w każdym przypadku, niezmiennie chcę dopasować na 0123456789, nigdy nie chcę dopasowywać na٠١٢٣٤٥٦٧٨٩
, i nie mogę wymyślić przypadku użycia, w którym ktoś chciałby dopasować cyfrę dziesiętną w dowolnym skrypcie z narzędziami POSIX. Zobacz także bieżącą dyskusję[:blank:]
na temat zsh ML . Te klasy postaci są trochę bałaganu.Zależy to od sposobu zdefiniowania cyfry;
[0-9]
zwykle są to ASCII (lub być może coś innego, co nie jest ani ASCII ani nadzbiorem ASCII, ale ma takie same 10 cyfr jak w ASCII tylko z różnymi reprezentacjami bitów (EBCDIC));\d
z drugiej strony mogą to być zwykłe cyfry (stare wersje Perla lub nowoczesne wersje Perla z/a
włączoną flagą wyrażeń regularnych) lub może to być dopasowanie Unicode,\p{Digit}
które jest raczej większym zestawem cyfr niż[0-9]
lub/\d/a
pasuje.perldoc perlrecharclass
aby uzyskać więcej informacji lub zajrzyj do dokumentacji danego języka, aby zobaczyć, jak się on zachowuje.Ale czekaj, jest więcej! Ustawienia regionalne mogą również różnić się w zależności od tego
\d
, co pasuje, więc\d
może pasować do mniejszej liczby cyfr niż pełny zestaw takich Unicode, i (mam nadzieję, że zwykle) także[0-9]
. Jest to podobne do różnicy w C pomiędzyisdigit(3)
([0-9]
) iisnumber(3)
([0-9
plus cokolwiek innego z ustawień regionalnych).Mogą istnieć połączenia, które można wykonać w celu uzyskania wartości cyfry, nawet jeśli nie jest to
[0-9]
:źródło
isnumber()
to kwestia BSD, przynajmniej na podstawie strony[0-9]
.Inny sens
[0-9]
,[[:digit:]]
a\d
prezentowane są w innych odpowiedzi. W tym miejscu chciałbym dodać różnice w implementacji silnika regex.Tak
[[:digit:]]
zawsze działa ,\d
zależy. W instrukcji grep na to wspomnieć, że[[:digit:]]
to właśnie0-9
w tejC
lokalizacji.PS1: Jeśli wiesz więcej, rozwiń tabelę.
PS2: GNU grep 3.1 i GNU 4.4 jest używany do testu.
źródło
grep
ised
, z największą różnicą prawdopodobnie między wersjami GNU a innymi. Ta odpowiedź może być bardziej przydatna, jeśli wspomina o której wersjigrep
i dosed
której się odnosi. Albo jakie jest źródło tej tabeli. 2) ta tabela może być również przepisana na tekst, ponieważ nie zawiera niczego, co wymagałoby, aby był to obrazre
moduł Pythona nie obsługuje [[: digit:]], ale biblioteka dodawaniaregex
obsługuje go, więc bym trochę podrywał na zawsze działa. Zawsze działa w sytuacjach skarg posix.Różnice teoretyczne zostały już dość dobrze wyjaśnione w innych odpowiedziach, więc pozostaje wyjaśnienie różnic praktycznych .
Oto niektóre z najczęstszych przypadków użycia dla dopasowania cyfry:
Ekstrakcja danych jednym strzałem
Często, gdy chcesz rozbić niektóre liczby, same numery znajdują się w niezgrabnie sformatowanym pliku tekstowym. Chcesz je wyodrębnić do wykorzystania w twoim programie. Prawdopodobnie możesz określić format liczb (patrząc na plik) i swoje bieżące ustawienia narodowe, więc możesz użyć dowolnego formularza , o ile wykona on zadanie.
\d
wymaga najmniejszej liczby naciśnięć klawiszy, więc jest to bardzo często używane.Wprowadzanie środków dezynfekujących
Masz pewne niezaufane dane wejściowe użytkownika (być może z formularza internetowego) i musisz upewnić się, że nie zawiera żadnych niespodzianek. Być może chcesz zapisać go w polu numerycznym w bazie danych lub użyć jako parametru polecenia powłoki do uruchomienia na serwerze. W tym przypadku naprawdę chcesz
[0-9]
, ponieważ jest to najbardziej restrykcyjny i przewidywalny.Walidacji danych
Masz trochę danych, których nie wykorzystasz do niczego „niebezpiecznego”, ale dobrze byłoby wiedzieć, czy jest to liczba. Na przykład twój program pozwala użytkownikowi na wprowadzenie adresu, a Ty chcesz zaznaczyć literówkę, jeśli dane wejściowe nie zawierają numeru domu. W takim przypadku prawdopodobnie chcesz być tak szeroki, jak to możliwe, tak też
[[:digit:]]
jest droga.Wydaje się, że są to trzy najczęstsze przypadki użycia dopasowania cyfr. Jeśli uważasz, że przegapiłem ważny, proszę zostaw komentarz.
źródło