Unterschied zwischen .* und * im regulären Ausdruck

Unterschied zwischen .* und * im regulären Ausdruck

Ich habe eine Datei namens "test", die enthält

linux
Unixlinux
Linuxunix
it's linux
l...x

Wenn ich jetzt verwende grep '\<l.*x\>', entspricht es:

linux
it's linux
l...x

aber wenn ich verwende grep '\<l*x\>', stimmt es nur mit Folgendem überein:

l...x, aber laut Referenzhandbuch wird bei Verwendung von * das vorhergehende Element null oder mehrmals abgeglichen, d. h. es sollte auf alles passen, was mit „l“ beginnt und mit „x“ endet.

Kann mir jemand erklären, warum nicht das gewünschte Ergebnis angezeigt wird oder ob ich es falsch verstanden habe?

Antwort1

Notation (.*)

Das * in den regulären Ausdrücken .* und * bezieht sich auf eine Anzahl, nicht auf Zeichen an sich, genauer gesagt bedeutet es„Null oder mehr“. Darüber hinaus.bedeutet'jedes einzelne Zeichen'.

Wenn Sie sie also zusammenfügen, erhalten Sie„null oder mehr beliebige Zeichen“. Zum Beispiel Zeichenfolgen wie diese:

  • linux
  • Abonnieren
  • lnx
  • hallo linux
  • lx

Würde übereinstimmen mit <l.*x>. Das letzte ist wichtig, es zeigt, dass die.*kann auch nichts mithalten.

Notation (*)

Die Verwendung von * allein ist wie gesagt ein Zähler. Wenn Sie es also nach einem Buchstaben wie'ich'das * sagt'null oder mehr von l'.

Beachten Sie, dass wenn wir nach greppen l*x, dies mit übereinstimmt l...x, aber wahrscheinlich nicht aus dem Grund, den Sie vermuten.

% echo "l...x" | grep "l*x"
l...x

Es wird auf das nachfolgende 'x' abgeglichen. Das 'l' hat nichts damit zu tun, warum dies abgeglichen wird, außer der Tatsache, dass dem 'x' vorangestellt ist„null oder mehr l“.

Antwort2

Wenn Sie nach etwas suchen, das mit „l“ beginnt und mit „x“ endet, versuchen Sie es mit dem regulären Ausdruck „l.*x“. Dabei sind „.“ und „*“ Sonderzeichen, die ein einzelnes gültiges Zeichen bzw. Zeichen mit einer Länge von mindestens null darstellen. Vor „*“ steht hier ein „.“, sodass alles, was an die Stelle von „.“ kommt, gemäß der Definition von „*“ wie oben wiederholt wird.

Antwort3

Für die Shell (z. B. Bash) werden Joker zum Abgleichen von Dateinamen verwendet *und ?sind die Zeichen selbst – sie stellen die Zeichen dar.

Bei regulären Ausdrücken hingegen sind , *, (Vorkommensbereich) und ( nur) für sich genommen nichts. Sie beziehen sich immer auf das vorherige Zeichen/Atom – egal, ob es sich dabei um ein tatsächliches Zeichen handelt (z. B. ?oder ) , den (Joker), der jedes beliebige Zeichen, einen Bereich von Zeichen (z. B. ) oder ein Muster aus mehreren Zeichen (nur egrep; z. B. – wobei „abba“ als Einheit betrachtet wird). Die und stellen daher für sich genommen nichts dar, sagen aber etwas darüber aus, wie oft das vorherige Zeichen (das ein Joker für jedes beliebige Zeichen oder eine als Einheit behandelte Gruppe sein kann) wiederholt werden soll.{n,m}+egrepL5.[a-f](abba)*?

Wenn Sie sich diesen Unterschied zwischen der Art und Weise, wie Shell und reguläre Ausdrücke das *„und“ verwenden ?, erst einmal merken, sollte alles klar sein.

Also für reguläre Ausdrücke:

  • .- stellt genau ein Vorkommen eines beliebigen Zeichens dar
  • a..a- passt zu zwei a's mit zwei beliebigen Zeichen dazwischen
  • .*- entspricht 0, 1 oder mehr Vorkommen eines beliebigen Zeichens
  • B*- entspricht 0, 1 oder mehr Vorkommen von „B“

verwandte Informationen