Ich habe diese Frage in SuperUser beantwortet , die sich auf reguläre Ausdrücke bezieht, die beim Greifen einer Ausgabe verwendet werden.
Die Antwort, die ich gab, war folgende:
tail -f log | grep "some_string.*some_string"
Und dann schrieb @Bob in drei Kommentaren zu meiner Antwort Folgendes :
.*
ist gierig und könnte mehr erfassen, als Sie wollen..*?
ist normalerweise besser.
Dann das,
Das
?
ist ein Modifikator*
, der es faul macht, anstatt den gierigen Standard. Angenommen, PCRE.
Ich habe gegoogelt PCRE
, konnte aber in meiner Antwort nicht verstehen , welche Bedeutung dies hat.
und schließlich das,
Ich sollte auch darauf hinweisen, dass dies Regex ist (grep macht standardmäßig POSIX Regex), kein Shell Glob.
Ich weiß nur, was ein Regex ist und wie er im Befehl grep sehr einfach verwendet wird. Daher konnte ich keinen dieser drei Kommentare erhalten und habe folgende Fragen:
- Was sind Unterschiede in der Nutzung von
.*?
vs..*
? - Was ist besser und unter welchen Umständen? Bitte geben Sie Beispiele an.
Auch wäre es hilfreich, die Kommentare zu verstehen, wenn jemand könnte
UPDATE: Als Antwort auf die Frage Wie unterscheidet sich Regex von Shell Globs? @Kusalananda hat diesen Link in seinem Kommentar angegeben.
HINWEIS: Falls erforderlich, lesen Sie bitte meine Antwort auf diese Frage, bevor Sie antworten, um auf den Kontext zu verweisen.
quelle
.*
vs..*?
bezieht. Die Frage "Unterschied zwischen regulären Ausdrücken und Shell-Globs" wurde bereits auf dieser Site behandelt.Antworten:
Ashok hat bereits auf den Unterschied zwischen
.*
und hingewiesen.*?
, daher werde ich nur einige zusätzliche Informationen bereitstellen.grep
(unter der Annahme der GNU-Version) unterstützt 4 Möglichkeiten, Zeichenfolgen abzugleichen:grep
verwendet standardmäßig BRE.BRE und ERE sind im Kapitel " Reguläre Ausdrücke" von POSIX dokumentiert, und PCRE ist auf seiner offiziellen Website dokumentiert . Bitte beachten Sie, dass Funktionen und Syntax zwischen den Implementierungen variieren können.
Es ist erwähnenswert, dass weder BRE noch ERE Faulheit unterstützen :
Wenn Sie diese Funktion verwenden möchten, müssen Sie stattdessen PCRE verwenden:
Bearbeiten 1
.*
wird verwendet, um das "längste" 1 mögliche Muster abzugleichen..*?
wird verwendet, um das "kürzeste" 1 mögliche Muster abzugleichen.Nach meiner Erfahrung ist das meistgesuchte Verhalten normalerweise das zweite.
Nehmen wir zum Beispiel an, wir haben die folgende Zeichenfolge und möchten nur die HTML-Tags 2 abgleichen , nicht den Inhalt zwischen ihnen:
Jetzt vergleiche
.*
vs.*?
:1. Die Bedeutung von "am längsten" und "am kürzesten" in einem Regex-Kontext ist etwas schwierig, wie Kusalananda betonte . Weitere Informationen finden Sie in der offiziellen Dokumentation.
2. Es wird nicht empfohlen, HTML mit Regex zu analysieren . Dies ist nur ein Beispiel für Bildungszwecke. Verwenden Sie es nicht in der Produktion.
quelle
.*
vs erklären.*?
?Angenommen, ich nehme eine Zeichenfolge wie:
can cats eat plants?
Die Verwendung von gierig
c.*s
stimmt mit der gesamten Zeichenfolge überein, da sie mit beginntc
und mit endet. Alss
gieriger Operator stimmt sie bis zum endgültigen Auftreten von s weiter überein.Während die Verwendung der Lazy
c.*?s
nur übereinstimmt, bis das erste Vorkommen vons
gefunden wird, dh Zeichenfolgecan cats
.Aus dem obigen Beispiel können Sie möglicherweise Folgendes entnehmen:
"Gierig" bedeutet, dass die längste mögliche Zeichenfolge gefunden wird. "Lazy" bedeutet, die kürzestmögliche Zeichenfolge zu finden. Hinzufügen eines
?
zu einem quantifier wie*
,+
,?
oder{n,m}
es faul macht.quelle
cats
, also wird "kürzestmöglich" nicht streng in diesem Sinne durchgesetzt.Eine Zeichenfolge kann auf verschiedene Arten abgeglichen werden (von einfach bis komplexer):
Als statische Zeichenfolge (Angenommen, var = 'Hello World!'):
Shell
[ "$var" = "Hello World!" ] && echo yes
Grep
echo "$var" | grep -F "Hello"
Bash
grep -F "Hello" <<<"$var"
Als Globus:
Shell
echo ./*
# listet alle Dateien in pwd auf.
Shell
case $var in (*Worl*) echo yes;; (*) echo no;; esac
Bash
[[ "$var" == *"Worl"* ]] && echo yes
Es gibt einfache und erweiterte Globs. Im
case
Beispiel werden grundlegende Globs verwendet. Im Bash-[[
Beispiel werden erweiterte Globs verwendet. Die erste Dateiübereinstimmung kann einfach sein oder auf einer Shell wie der Einstellungextglob
in Bash erweitert werden. Beide sind in diesem Fall identisch. Grep konnte keine Globs verwenden.Das Sternchen in einem Globus bedeutet etwas anderes als ein Sternchen in einem regulären Ausdruck :
Glob
* matches any number (including none) of
alle Zeichen .Regex
* matches any number (including none) of the
vorhergehendes Element .Als grundlegender regulärer Ausdruck (BRE):
sed
echo "$var" | sed 's/W.*d//'
# print: Hallo!
grep
grep -o 'W.*d' <<<"$var"
# print World!
Es gibt kein BRE in (Grund-) Muscheln oder Awk.
Erweiterte reguläre Ausdrücke (ERE):
bash
[[ "$var" =~ (H.*l) ]]
# match: Hello Worl
sed
echo "$var" | sed -E 's/(d|o)//g'
# print: Hell Wrl!
awk
awk '/W.*d/{print $1}' <<<"$var"
# print: Hallo
grep
grep -oE 'H.*l' <<<"$var"
# print: Hallo Welt
Perl-kompatible reguläre Ausdrücke:
grep
grep -oP 'H.*?l
# print: Hel
Nur in einer PCRE
*?
hat a eine bestimmte Syntaxbedeutung.Es macht das Sternchen faul (unhöflich): Faulheit statt Gier .
Dies ist nur die Spitze des Eisbergs, es gibt gierige, faule und fügsame oder besitzergreifende . Es gibt auch Lookahead und Lookbehind, aber diese gelten nicht für das Sternchen
*
.Es gibt eine Alternative, um den gleichen Effekt wie bei einem nicht gierigen regulären Ausdruck zu erzielen:
Die Idee ist sehr einfach: Verwenden Sie keinen Punkt
.
, negieren Sie das nächste übereinstimmende Zeichen[^o]
. Mit einem Web-Tag:Das Obige sollte alle @ Bob 3-Kommentare vollständig verdeutlichen. Umschreibung:
.*
ist gierig.*?
ist nicht.Fragen
Was sind Unterschiede in der Verwendung von. ? vs. ?
.*?
ist nur in der PCRE-Syntax gültig..*
ist tragbarer.[^a]*
Was ist besser und unter welchen Umständen? Bitte geben Sie Beispiele an.
Besser? Es kommt auf das Ziel an. Es gibt kein besseres, jedes ist für verschiedene Zwecke nützlich. Ich habe oben einige Beispiele angegeben. Brauchst du mehr?
quelle