Mit https://regex101.com/ habe ich einen regulären Ausdruck erstellt, um das erste Auftreten einer IP-Adresse in einer Zeichenfolge zurückzugeben.
RegExp:
(?:\d{1,3}\.)+(?:\d{1,3})
RegExp einschließlich Trennzeichen:
/(?:\d{1,3}\.)+(?:\d{1,3})/
Mit der folgenden Testzeichenfolge:
eu-west 140.243.64.99
Es wird eine vollständige Übereinstimmung zurückgegeben von:
140.243.64.99
Egal, was ich mit Ankern usw. versuche, das folgende Bash-Skript funktioniert nicht mit dem generierten regulären Ausdruck.
temp="eu-west 140.243.64.99 "
regexp="(?:\d{1,3}\.)+(?:\d{1,3})"
if [[ $temp =~ $regexp ]]; then
echo "found a match"
else
echo "No IP address returned"
fi
bash
regular-expression
rjm61
quelle
quelle
=~
Operator wird hier im Handbuch erläutert , wo die geschriebene Bash "erweiterte reguläre Ausdrücke" verwendet. Erweiterte reguläre Ausdrücke sind in der beschriebenenregex(7)
Manpage und kurz zusammengefasst hier .Antworten:
\d
ist eine nicht standardmäßige Art, "jede Ziffer" zu sagen. Ich denke, es kommt von Perl, und viele andere Sprachen und Dienstprogramme unterstützen auch Perl-kompatible REs (PCRE). (und z. B. unterstützt GNU grep 2.27 in Debian Stretch das Gleiche\w
für Wortzeichen auch im normalen Modus.)Bash wird jedoch nicht unterstützt
\d
, daher müssen Sie explizit[0-9]
oder verwenden[[:digit:]]
.(?:..)
Verwenden Sie(..)
stattdessen das Gleiche für die nicht erfassende Gruppe .Dies sollte drucken
match
:quelle
grep
Unterstützt Ihre GNU\d
ohne-P
?\w
und\b
, was ich von Perl gelernt habe, also habe ich das verwirrt.\d
oder PCRE sind "nicht Standard". Sie sind ziemlich Standard, nur ein anderer Standard als ursprüngliche reguläre Ausdrücke und erweiterte reguläre Ausdrücke.\d
. Obwohl Sie Recht haben, sind PCRE eher Standard oder am wenigsten genau definiert. Das lästige Problem ist , dass GNU grep (oder glibc) unterstützt einige PCRE artige Atome, zumindest\w
und\s
wenn ERE zu interpretieren, und in diesem Zusammenhang sie sehr viel sind Nicht - Standard. Meine Formulierung könnte teilweise darauf zurückzuführen sein, und auf die falsche Erinnerung,\d
die ebenfalls von der GNU unterstützt wurde.(:...)
und\d
sind Perl- oder PCRE-Operatoren für reguläre Ausdrücke (wie in GNUgrep -P
).bash
Unterstützt nur erweiterte reguläre Ausdrücke wie in, mit dergrep -E
Ausnahme, dass für reguläre Ausdrücke , die buchstäblich als in übergeben werden,[[ text =~ regexp-here ]]
im Gegensatz zu als Ergebnis einer nicht zitierten Erweiterung (wie in[[ text =~ $var ]]
oder[[ test =~ $(printf '%s\n' 'regexp-here') ]]
), diese auf den erweiterten POSIX-Funktionsumfang für reguläre Ausdrücke beschränkt ist.Selbst auf Systemen, auf denen
grep -E '\d'
dies funktionieren würde (GNU EREs haben bereits einige Erweiterungen aus Perl-Regexps importiert, wie\s
dies auch in zukünftigen Versionen der Fall sein könnte\d
), müssten Sie Folgendes verwenden:in
bash
für sie (arbeiten[[ $text =~ \d ]]
würde nicht).Für eine Shell, die PCREs unterstützt, möchten Sie möglicherweise Folgendes verwenden
zsh
:ksh93 unterstützt im Rahmen des Pattern Matching auch die eigene Implementierung von Perl-ähnlichen regulären Ausdrücken (nicht vollständig kompatibel). Dort würden Sie verwenden:
(Beachten Sie die
=
anstelle von=~
. Sie sollten temporäre Variablen verwenden, da dies sehr fehlerhaft ist, wenn Sie dies nicht tun.)quelle
Die Site regex101.com verwendet standardmäßig PCRE (siehe obere linke Ecke) und unterstützt die "erweiterte" Regex-Syntax nicht. Das sind "Perl-kompatible reguläre Ausdrücke", die (wie zu erwarten) von Perl stammen.
PCRE wird
grep -P
unter bestimmten Bedingungen von einigen Tools (wie ) unterstützt , aber die Bash-Regex-Unterstützung innerhalb des[[…]]
Idioms gilt nur für erweiterten Regex (wiegrep -E
).In Extended Regex existiert die Nicht-Capture-
(?…)
Klammer nicht und das \ d fehlt ebenfalls. Sie müssen einfach(…)
und verwenden[0-9]
:quelle