Grep Regex Ergebnis nicht wie erwartet?

534
Stilez

FreeBSD 11.1 verwenden:

#!/bin/sh  if printf 'abcde.fgh' | grep -iEq '^[^][$^*_-]'; then echo "test 1 success" else echo "test 1 fail" fi  echo  if printf 'abcde.fgh' | grep -iEq '^[^][.$^*_-]'; then echo "test 2 success" else echo "test 2 fail" fi 

Ausgabe:

test 1 success  grep: Unmatched [ or [^ test 2 fail 

Aber AFAICT diese sollten das gleiche Ergebnis ergeben. Beide enthalten eine Bedingung für das erste Zeichen (nur), dass es nicht zu einer Liste von angegebenen nicht alphabetischen Zeichen gehört. Aufgliederung der Regex:

  • ^ = Anfang der Zeichenfolge
  • [^...] = passen, wenn keines dieser Zeichen
  • Innerhalb der Liste ]muss das erste Zeichen sein, ^darf nicht das erste und - muss das letzte Zeichen sein. Es gibt also ][.^$_-eine gültige Liste von Literalzeichen, und die Zeichenfolge darf mit keinem von ihnen übereinstimmen.
  • Um Verwirrung zu vermeiden, beachten Sie, dass dies das ][Literal "]"und die "["Zeichen in der Liste und nicht das Schließen und Wiederöffnen von 2 Listen bedeutet.

Der einzige Unterschied zwischen den beiden Ausdrücken ist der, "."aber er befindet sich in einer Liste. Daher sollte er so behandelt werden, not literal .dass das erste Zeichen nicht mit dem Literal übereinstimmt"."

Was vermisse ich? Etwas sehr offensichtliches und einfaches, wahrscheinlich?

2

1 Antwort auf die Frage

3
grawity

Ihnen fehlen einige andere Syntaxregeln. Innerhalb einer Klammererweiterung gibt es neben einfachen Bereichen auch einige Arten von Ausdrücken mit mehreren Zeichen, die mit a beginnen [. (Weitere Informationen finden Sie im Regex- Handbuch (7) für Linux oder FreeBSD unter "Mit Ausnahme dieser und einiger Kombinationen, die" [" (siehe nächste Absätze)) verwenden.] Dies sind:

  • Sortierelemente: [..]
  • Äquivalenzklassen: [==]
  • Charakterklassen: [::]

(Möglicherweise haben Sie solche Ausdrücke als solche gesehen oder verwendet [[:digit:]]- diese sind eigentlich eine Zeichenklasse [:digit:], die das einzige Element einer […]Klammererweiterung ist.)

Da in Ihrem Fall .also unmittelbar nach a geschieht, werden [sie als Öffnungsbegrenzer eines Vergleichselements erkannt. GNU grep 3.1 hat die korrekte Fehlermeldung:

$ printf 'abcde.fgh' | grep -iEq '^[^][.$^*_-]' grep: Unmatched [, [^, [:, [., or [= 

Die gleichen Ausdrücke können solche Situationen verwendet werden, zu entkommen, indem zB mit [...]oder [=.=]einem regulären Punkt zu schließen, oder auf ähnliche Weise [=-=]einen Strich zu passen, wenn es nirgendwo ist sie zu bewegen.

Ähhh. Macht Sinn. Ich habe nicht nach einer anderen Multicharakter-Klassensyntax gesucht, die vielleicht ähnelt, also war das mein Horizont. Vielen Dank! Stilez vor 5 Jahren 0