Warum stimmt '[az] *' mit nicht alphabetischen Zeichenfolgen überein?

9

Ich habe eine Datei alphanummit diesen beiden Zeilen:

123 abc
this is a line

Ich bin verwirrt, warum ich beim Ausführen sed 's/[a-z]*/SUB/' alphanumdie folgende Ausgabe erhalte:

SUB123 abc
SUB is a line

Ich habe erwartet:

123 SUB
SUB is a line

Ich habe ein Update gefunden ( sed 's/[a-z][a-z]*/SUB/'stattdessen verwenden), aber ich verstehe nicht, warum es funktioniert und meins nicht.

Kannst du helfen?

Fakher Mokadem
quelle
@Kamaraj, das ist ähnlich, hat aber die Shell-Muster gegen Regexes Verwirrung oben (und die Antworten konzentrieren sich auf die ersteren, da das ist, was die ls foo*dort verwendet). Wenn Sie jedoch doppelte Fragen finden, sollten Sie diese auch als solche kennzeichnen können.
Ilkkachu
Schauen Sie sich regexr.com für Live-Visuals und
Erklärungen an
@RozzA Beachten Sie, dass die Website, auf die Sie verlinken, reguläre Javascript- und Perl-Ausdrücke unterstützt, keine regulären POSIX-Ausdrücke.
Kusalananda

Antworten:

28

Das Muster [a-z]*entspricht null oder mehr Zeichen im Bereich avon z(die tatsächlichen Zeichen hängen vom aktuellen Gebietsschema ab). Es gibt null solcher Zeichen am Anfang der Zeichenfolge 123 abc(dh das Muster stimmt überein) und auch vier davon am Anfang von this is a line.

Wenn Sie mindestens eine Übereinstimmung benötigen , verwenden Sie [a-z][a-z]*oder [a-z]\{1,\}oder aktivieren Sie erweiterte reguläre Ausdrücke mit sed -Eund verwenden Sie [a-z]+.

Fügen Sie Klammern um jede Übereinstimmung hinzu, um zu visualisieren, wo das Muster übereinstimmt:

$ sed 's/[a-z]*/(&)/' file
()123 abc
(this) is a line

Oder um alle Übereinstimmungen in den Zeilen zu sehen:

$ sed 's/[a-z]*/(&)/g' file
()1()2()3() (abc)
(this) (is) (a) (line)

Vergleichen Sie das letzte Ergebnis mit

$ sed -E 's/[a-z]+/(&)/g' file
123 (abc)
(this) (is) (a) (line)
Kusalananda
quelle
7
Technisch [a-z]Spiele Zusammentragelemente , die aus mehr als einem Zeichen gemacht werden kann. Zum Beispiel in einigen ungarischen Gegenden [a-z]Spiele amdzs
Stéphane Chazelas
12

Da *Streichhölzer null oder mehr Wiederholungen des vorherigen Atom und alle regex Motoren versuchen , das erste Spiel zu finden. Am Anfang Ihrer Zeichenfolge befindet sich eine Teilzeichenfolge mit genau null Buchstaben. In dem Fall, in dem die Zeichenfolge mit einem Buchstaben beginnt, werden *so viele Übereinstimmungen wie möglich angezeigt. Dies ist jedoch zweitrangig, um die Übereinstimmung ganz links zu finden.

Übereinstimmungen mit der Länge Null können etwas problematisch sein. Wie Sie gesehen haben, besteht die Lösung darin, das Muster so zu ändern, dass mindestens ein Zeichen erforderlich ist. Mit erweiterten regulären Ausdrücken könnten Sie +dafür:sed -E 's/[a-z]+/SUB/'

Versuchen Sie zum Spaß:

echo 'less than 123 words' | sed 's/[0-9]*/x/g'
ilkkachu
quelle