Heim  >  Artikel  >  Backend-Entwicklung  >  PHP – Leistung regulärer PCRE-Ausdrücke

PHP – Leistung regulärer PCRE-Ausdrücke

伊谢尔伦
伊谢尔伦Original
2016-11-21 17:08:471232Durchsuche

Einige Elemente im Muster sind möglicherweise effizienter als andere. Beispielsweise ist die Verwendung einer Zeichenklasse wie [aeiou] effizienter als der optionale Pfad (a|e|i|o|u). Im Allgemeinen sind Anforderungen dann am lustigsten, wenn sie in einem möglichst einfachen Konstrukt beschrieben werden. Jeffrey Friedls Buch (Mastering Regular Expressions) enthält viele Diskussionen über die Leistung regulärer Ausdrücke.

Wenn ein Muster mit .* beginnt und die Option PCRE_DOTALL festgelegt ist, wird das Muster implizit durch PCRE verankert, da es mit dem Anfang der Zeichenfolge übereinstimmt. Wenn PCRE_DOTALL jedoch nicht festgelegt ist, kann PCRE diese Optimierung nicht durchführen, da das Metazeichen nicht mit Zeilenumbrüchen übereinstimmen kann und wenn die Zielzeichenfolge Zeilenumbrüche enthält, beginnt der Abgleich des Musters möglicherweise nach einem Zeilenumbruch und nicht am Anfang. Beispielsweise entspricht das Muster (.*) Sekunde der Zielzeichenfolge „erster und zweiter“ (n ist ein Zeilenumbruchzeichen) und das erste erfasste Untergruppenergebnis ist „und“. Zu diesem Zweck versucht PCRE, nach jedem Zeilenumbruchzeichen in der Zielzeichenfolge eine Übereinstimmung zu finden.

Wenn Sie ein Muster verwenden, um eine Zielzeichenfolge ohne Zeilenumbrüche abzugleichen, können Sie die Verankerung explizit angeben, indem Sie PCRE_DOTALL oder ein Muster festlegen, das mit ^.* beginnt, um die beste Leistung zu erzielen. Dies erspart PCRE die Zeit, bei der Suche entlang der Zielzeichenfolge nach einem Zeilenumbruchzeichen von vorne beginnen zu müssen.

Achten Sie auf die Verschachtelung unendlicher Wiederholungen in Mustern. Dies kann bei der Anwendung auf nicht übereinstimmende Zeichenfolgen zu langen Laufzeiten führen. Betrachten Sie das Musterfragment (a )*.

Dieses Muster kann auf 33 Arten mit „aaaa“ übereinstimmen, und diese Zahl erhöht sich schnell, wenn die Länge der Zeichenfolge zunimmt (*Wiederholungen können 0,1,2,3,4 Mal und in jedem Fall übereinstimmen hat eine andere Anzahl von Übereinstimmungen als 0). Wenn der Rest des Musters dazu führt, dass die gesamte Übereinstimmung fehlschlägt, probiert PCRE grundsätzlich jede mögliche Variation aus, was sehr zeitaufwändig sein kann.

Die Optimierung für einige einfache Fälle besteht darin, die Originalzeichenfolge sofort wie (a)*b zu verwenden. Bevor mit der formalen Matching-Arbeit begonnen wird, prüft PCRE, ob nach der Zielzeichenfolge ein „b“-Zeichen steht, und schlägt sofort fehl, wenn dies nicht der Fall ist. Diese Optimierung ist jedoch nicht verfügbar, wenn keine Originalzeichen unmittelbar folgen. Sie können die Verhaltensunterschiede zwischen (a )*d und dem obigen Muster vergleichen und beobachten. Ersteres meldet fast sofort einen Fehler, wenn es auf eine Zeichenfolge angewendet wird, die in der gesamten Zeile aus „a“ besteht, während letzteres viel Zeit in Anspruch nimmt, wenn die Zielzeichenfolge länger als 20 Zeichen ist.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn