Im Wikipedia-Artikel über reguläre Ausdrücke scheint [[:digit:]]
= [0-9]
= \d
.
Was sind die Umstände, unter denen sie nicht gleich sind? Was ist der Unterschied?
Nach einigen Recherchen denke ich, dass ein Unterschied darin besteht, dass der Klammerausdruck [:expr:]
vom Gebietsschema abhängt.
regular-expression
wildcards
Harbinn
quelle
quelle
Antworten:
Ja, es ist
[[:digit:]]
~[0-9]
~\d
(wobei ~ ungefähr bedeutet).In den meisten Programmiersprachen (
\d
sofern unterstützt) ≡[[:digit:]]
(identisch).Das
\d
ist weniger verbreitet als[[:digit:]]
(nicht in POSIX, aber es ist in GNUgrep -P
).In UNICODE gibt es viele Ziffern , zum Beispiel:
123456789 # Hindu-Arabic
arabische Ziffern٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI
All dies kann in
[[:digit:]]
oder enthalten sein\d
.Stattdessen stehen
[0-9]
in der Regel nur die ASCII-Ziffern0123456789
.Es gibt viele Sprachen: Perl, Java, Python, C. In denen
[[:digit:]]
(und\d
) nach einer erweiterten Bedeutung verlangt. Dieser Perl-Code stimmt beispielsweise mit allen Ziffern von oben überein:Dies entspricht der Auswahl aller Zeichen mit den Unicode-Eigenschaften von
Numeric
unddigits
:Welches grep reproduzieren könnte (die spezifische Version von pcre hat möglicherweise eine andere interne Liste numerischer Codepunkte als Perl):
Ändern Sie es auf [0-9], um Folgendes anzuzeigen:
POSIX
Für das spezifische POSIX BRE oder ERE:
Das
\d
wird nicht unterstützt (nicht in POSIX, sondern in GNUgrep -P
).[[:digit:]]
wird von POSIX benötigt, um der Ziffernklasse zu entsprechen, die wiederum von ISO C benötigt wird, um die Zeichen 0 bis 9 und nichts anderes zu sein. Also nur in C locale alle[0-9]
,[0123456789]
,\d
und[[:digit:]]
bedeutet genau das gleiche. Das[0123456789]
hat keine möglichen Fehlinterpretationen,[[:digit:]]
ist in mehr Dienstprogrammen verfügbar und gemeinhin nur gemeint[0123456789]
. Das\d
wird von wenigen Dienstprogrammen unterstützt.Was
[0-9]
ist die Bedeutung des Bereichs Ausdrücke nur von POSIX in der C - Sprache definiert; In anderen Ländern kann es anders sein (Codepoint-Reihenfolge oder Sortierreihenfolge oder etwas anderes).Muscheln
Einige Implementierungen verstehen einen Bereich möglicherweise als etwas anderes als eine reine ASCII-Reihenfolge (z. B. ksh93):
Und das ist eine sichere Quelle von Fehlern, die darauf warten, passiert zu werden.
quelle
iswctype()
und BRE / ERE / Wildcards in POSIX-Dienstprogrammen stimmen [0-9] und [[: digit:]] nur mit 0123456789 überein. Und das wird in der nächsten Überarbeitung des Standardsperl
‚s\d
im Unicode - Modus von anderen Skripten auf Dezimalstellen angepasst. Dank dafür. Informationen zu PCRE finden Sie(*UCP)
in GNUgrep -Po '(*UCP)\d'
odergrep -Po '(*UCP)[[:digit:]]
für Klassen, die auf Unicode-Eigenschaften basieren.[:digit:]
Syntax nahe legt, dass Sie die Lokalisierung verwenden möchten. Dies ist alles, was der Benutzer als Ziffer ansieht. Ich benutze es nie,[:digit:]
weil es in der Praxis das Gleiche ist[0-9]
und auf jeden Fall, ich möchte immer mit 0123456789 übereinstimmen, ich möchte niemals mit übereinstimmen٠١٢٣٤٥٦٧٨٩
, und ich kann mir keinen Anwendungsfall vorstellen, in dem man mit einer Dezimalziffer übereinstimmen möchte in jedem Skript mit POSIX-Dienstprogrammen. Siehe auch die aktuelle Diskussion[:blank:]
zum zsh ML . Diese Charakterklassen sind ein bisschen chaotisch.Dies hängt davon ab, wie Sie eine Ziffer definieren.
[0-9]
neigt dazu, nur die ASCII zu sein (oder möglicherweise etwas anderes, das weder ASCII noch eine Obermenge von ASCII ist, sondern dieselben 10 Stellen wie in ASCII nur mit unterschiedlichen Bitdarstellungen (EBCDIC));\d
auf der anderen Seite könnte entweder nur die einfachen Ziffern (alte Versionen von Perl oder modernen Versionen von Perl mit dem seine/a
regulären Ausdruck Flag aktiviert) oder es könnte ein Unicode - Spiel von seinem\p{Digit}
der ist eher eine größere Anzahl von Ziffern als[0-9]
oder/\d/a
Spiel.perldoc perlrecharclass
Weitere Informationen finden Sie in der Dokumentation der jeweiligen Sprache.Aber warte, es gibt noch mehr! Das Gebietsschema kann auch variieren, welche Zeichen
\d
übereinstimmen, sodass möglicherweise\d
weniger Zeichen als der gesamte Unicode-Satz davon übereinstimmen und (hoffentlich normalerweise) auch enthalten[0-9]
. Dies ähnelt dem Unterschied in C zwischenisdigit(3)
([0-9]
) undisnumber(3)
([0-9
und was auch immer vom Gebietsschema abweicht).Möglicherweise können Anrufe getätigt werden, um den Wert der Ziffer abzurufen, auch wenn dies nicht der Fall ist
[0-9]
:quelle
isnumber()
ist eine BSD-Sache, zumindest basierend auf der Manpage scheint es so[0-9]
.Unterschiedliche Bedeutung von
[0-9]
,[[:digit:]]
und\d
sind in anderen Antworten präsentiert. Hier möchte ich Unterschiede in der Implementierung der Regex-Engine hinzufügen.Also klappt
[[:digit:]]
immer , kommt\d
drauf an. In greps Handbuch wird erwähnt, dass[[:digit:]]
es sich nur0-9
um dasC
Gebietsschema handelt.PS1: Wenn Sie mehr wissen, erweitern Sie bitte die Tabelle.
PS2: GNU grep 3.1 und GNU 4.4 werden zum Testen verwendet.
quelle
grep
undsed
, mit dem größten Unterschied zwischen den GNU-Versionen im Vergleich zu anderen. Diese Antwort ist möglicherweise nützlicher, wenn angegeben wird, auf welche Version vongrep
undsed
auf welche verwiesen wird. Oder wie die Quelle dieser Tabelle aussieht. 2)re
Modul [[: digit:]] nicht unterstützt, aber die Add-In-Bibliothekregex
es unterstützt, so dass ich ein wenig an den immer funktionierenden Funktionen herumknabbern würde. Es funktioniert immer in Posix-Beschwerdesituationen.Die theoretischen Unterschiede wurden bereits in den anderen Antworten ziemlich gut erklärt, so dass die praktischen Unterschiede noch zu erklären sind .
Hier sind einige der gängigsten Anwendungsfälle für den Abgleich einer Ziffer:
One-Shot-Datenextraktion
Wenn Sie einige Zahlen zusammenfassen möchten, befinden sich die Zahlen häufig in einer ungünstig formatierten Textdatei. Sie möchten sie zur Verwendung in Ihrem Programm extrahieren. Sie können sich wahrscheinlich das Zahlenformat sagen (um die Datei suchen) und aktuelle locale, so ist es in Ordnung , eine der Formen zu verwenden , solange er bekommt den Job getan.
\d
erfordert die wenigsten Tastenanschläge, daher wird es sehr häufig verwendet.Input-Desinfektion
Sie haben einige nicht vertrauenswürdige Benutzereingaben (möglicherweise über ein Webformular) und müssen sicherstellen, dass diese keine Überraschungen enthalten. Vielleicht möchten Sie es in einem numerischen Feld in einer Datenbank speichern oder als Parameter für einen Shell-Befehl verwenden, der auf einem Server ausgeführt werden soll. In diesem Fall möchten Sie wirklich
[0-9]
, da es das restriktivste und vorhersehbarste ist.Datenvalidierung
Sie haben einige Daten, die Sie nicht für "gefährliche" Zwecke verwenden werden, aber es wäre schön zu wissen, ob es sich um eine Zahl handelt. In Ihrem Programm kann der Benutzer beispielsweise eine Adresse eingeben, und Sie möchten einen möglichen Tippfehler hervorheben, wenn die Eingabe keine Hausnummer enthält. In diesem Fall möchten Sie wahrscheinlich so breit wie möglich sein
[[:digit:]]
.Dies scheinen die drei häufigsten Anwendungsfälle für die Ziffernanpassung zu sein. Wenn Sie der Meinung sind, dass ich ein wichtiges verpasst habe, schreiben Sie einen Kommentar.
quelle