26 Stimmen

Welche buchstäblichen Zeichen sollten in einem Regex escaped werden?

Ich habe gerade einen Regex für die Verwendung mit der PHP-Funktion preg_match geschrieben, der den folgenden Teil enthält:

[\w-.]

Um jedes Wortzeichen, sowie einen Minuszeichen und den Punkt, abzugleichen. Während es scheinbar in preg_match funktioniert, habe ich versucht, es in ein Hilfsprogramm namens Reggy einzufügen und es beschwert sich über "Leerer Bereich in Zeichenklasse". Versuch und Irrtum haben mir gezeigt, dass dieses Problem durch das Escapen des Minuszeichens gelöst wurde, wodurch der Regex in

[\w\-.]

umgewandelt wurde.

Da das Original in PHP zu funktionieren scheint, frage ich mich, warum ich das Minuszeichen escapen sollte oder nicht, und - da der Punkt auch ein Zeichen mit Bedeutung in PHP ist - warum ich den Punkt nicht escapen müsste. Liegt es daran, dass das von mir verwendete Hilfsprogramm unsinnig ist, dass es mit einem anderen Regex-Dialekt arbeitet oder dass mein Regex wirklich falsch ist und ich nur Glück habe, dass preg_match mir damit durchgehen lässt?

65voto

Bart Kiers Punkte 160101

In vielen Regex-Implementierungen gelten folgende Regeln:

Metazeichen innerhalb einer Zeichenklasse sind:

  • ^ (Negation)
  • - (Bereich)
  • ] (Ende der Klasse)
  • \ (Escape-Zeichen)

Daher müssen all diese Zeichen maskiert werden. Es gibt jedoch einige Ausnahmefälle:

  • - muss nicht maskiert werden, wenn es am Anfang oder Ende der Klasse steht ([abc-] oder [-abc]). In ziemlich vielen Regex-Implementierungen muss es auch nicht maskiert werden, wenn es direkt nach einem Bereich ([a-c-abc]) oder einer Kurzschreibweise für Zeichenklassen ([\w-abc]) steht. Das hast du beobachtet.
  • ^ muss nicht maskiert werden, wenn es nicht am Anfang der Klasse steht: [^a] bedeutet jedes Zeichen außer a, und [a^] entspricht entweder a oder ^, was gleichbedeutend ist mit: [\^a]
  • ] muss nicht maskiert werden, wenn es das einzige Zeichen in der Klasse ist: []] entspricht dem Zeichen ]

6voto

bw_üezi Punkte 4381
[\w.-]
  • Der . bedeutet normalerweise jedes Zeichen, aber zwischen [] hat es keine spezielle Bedeutung
  • - zwischen [] zeigt einen Bereich an, es sei denn, es ist maskiert oder entweder das erste oder letzte Zeichen zwischen []

4voto

Your Common Sense Punkte 154708

Obwohl einige Zeichen tatsächlich in einem Regex maskiert werden sollten, fragen Sie nicht nach regex, sondern nach Zeichenklasse. Wo das Bindestrichsymbol ein besonderes ist.

anstatt es zu maskieren, könnten Sie es ans Ende der Klasse setzen, [\w.-]

3voto

mario Punkte 141130

Der Punkt verliert seine Meta-Bedeutung in der Zeichenklasse.

Das - hat eine besondere Bedeutung in der Zeichenklasse. Wenn es nicht am Anfang oder am Ende der eckigen Klammern platziert wird, muss es maskiert werden. Andernfalls bezeichnet es einen Zeichenbereich (A-Z).

Sie haben jedoch ein weiteres Sonderfall ausgelöst. [\w-.] funktioniert, weil \w kein einzelnes Zeichen bezeichnet. Daher kann PCRE keinen Zeichenbereich erstellen. \w ist eine möglicherweise inkohärente Klasse von Symbolen, daher gibt es kein Endzeichen, das verwendet werden könnte, um den Bereich Z bis . zu erstellen. Außerdem würde der Punkt . dem ersten ASCII-Zeichen a vorausgehen, das \w möglicherweise finden könnte. Es gibt keinen konstruierbaren Bereich. Deshalb hat - ohne Maskierung bei Ihnen funktioniert.

0voto

Wenn Sie PHP verwenden und spezielle Regex-Zeichen escape müssen, benutzen Sie einfach preg_quote:

Ein Beispiel von php.net:

" . $word . "",
                          $textbody);
?>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X