Heim > Web-Frontend > js-Tutorial > Hauptteil

Effizienz der Verwendung regulärer Ausdrücke in PHP Detaillierte Erklärung von Greedy, Non-Greedy und Backtracking (mit Code)

php中世界最好的语言
Freigeben: 2018-03-30 10:51:55
Original
1398 Leute haben es durchsucht

Dieses Mal werde ich Ihnen eine detaillierte Erklärung der effizienten Greedy-, Non-Greedy- und Backtracking-Funktionen der Verwendung von Regularität in PHP (mit Code) geben. Hinweise zur Verwendung von Regularität in der Effizienz-Greedy-, Non-Greedy- und Backtracking-Funktion in PHP Was sind das? Hier sind tatsächliche Fälle.

Lassen Sie uns zunächst etwas über die Gier von regulären Ausdrücken lernen und was ist Nicht-Gier? Oder was ist ein Matching-Prioritätsquantifizierer und was ist ein Ignorieren des Prioritätsquantifizierers?

Okay, ich weiß nicht, was das Konzept ist, also geben wir ein Beispiel.

Ein Student wollte die Inhalte zwischen ihnen filtern. So schrieb er die regulären Regeln und Verfahren.

$str = preg_replace('%<script>.+?</script>%i','',$str);//非贪婪
Nach dem Login kopieren

Es scheint, als wäre daran nichts auszusetzen, aber in Wirklichkeit ist es nicht so. Wenn

$str = '<script<script>alert(document.cookie)</script>>alert(document.cookie)</script>';
Nach dem Login kopieren

, dann ist nach dem oben beschriebenen Verfahren das Ergebnis

$str = '<script<script>alert(document.cookie)</script>>alert(document.cookie)</script>'; 
$str = preg_replace('%<script>.+?</script>%i','',$str);//非贪婪 
print_r($str); 
//$str 输出为 <script>alert(document.cookie)</script>
Nach dem Login kopieren

, das immer noch nicht den gewünschten Effekt erzielen kann. Das Obige ist Nicht-Gier, und manche werden Faulheit genannt. Das Zeichen für Nichtgierigkeit ist die Menge Metazeichen gefolgt von ?, wie z. B. +?, *?, ?? (spezieller, ich werde in zukünftigen Blogs darüber schreiben) usw. Das bedeutet nicht gierig. Wenn Sie nicht schreiben?, bedeutet es gierig. Zum Beispiel:

$str = '<script<script>alert(document.cookie)</script>>alert(document.cookie)</script>'; 
$str = preg_replace('%<script>.+</script>%i','',$str);//非贪婪 
print_r($str); 
//$str 输出为 
Nach dem Login kopieren

Das Obige ist eine Einführung in den Unterschied zwischen gierig und nicht gierig. Lassen Sie uns als Nächstes über Backtracking-Probleme sprechen, die durch Gier und Nicht-Gier verursacht werden. Schauen wir uns zunächst ein kleines Beispiel an.

Der reguläre Ausdruck ist w*(d+) und die Zeichenfolge ist cfc456n. Was ist also der $1 dieser regulären Übereinstimmung? ?

Wenn Ihre Antwort 456 ist, dann herzlichen Glückwunsch, Ihre Antwort ist falsch. Das Ergebnis ist nicht 456, sondern 6. Wissen Sie warum?

CFC4N erklärt: Wenn die reguläre Engine das reguläre w*(d+) verwendet, um die Zeichenfolge cfc456n abzugleichen, verwendet sie zunächst w*, um die Zeichenfolge cfc456n abzugleichen. Zeichen und übergeben Sie es dann an d+, um es mit der verbleibenden Zeichenfolge abzugleichen, und der Rest ist weg. Zu diesem Zeitpunkt spuckt die w*-Regel widerstrebend ein Zeichen aus, damit d+ übereinstimmt. Gleichzeitig spuckt sie das Zeichen aus , notieren Sie einen Punkt, dieser Punkt ist der Punkt, der für die Rückverfolgung verwendet wird. Dann wird festgestellt, dass die Übereinstimmung nicht erfolgreich sein kann. W* wird zuerst einen Rückverfolgungspunkt aufzeichnen und dann ausspucken einen Charakter herausbringen. Zu diesem Zeitpunkt ist das Übereinstimmungsergebnis von w* nur cfc45, und 6n wurde erneut mit d+ übereinstimmt. Wenn festgestellt wird, dass die Übereinstimmung erfolgreich ist, wird dies der Fall sein direkt angezeigt. Daher ist das Ergebnis von (d+) 6 und nicht 456.

Wenn der obige reguläre Ausdruck in w*?(d+) geändert wird (beachten Sie, dass er hier nicht gierig ist), lautet die Zeichenfolge immer noch cfc456n. Was ist also zu diesem Zeitpunkt der reguläre passende $1? ?

Schüler A antwortete: Das Ergebnis ist 456.

Nun ja, richtig, es ist 456. CFC4N möchte fragen, warum es 456 ist?

Lassen Sie mich erklären, warum es 456 ist

Es gibt eine Regel, dass Quantoren zuerst abgeglichen werden, also wird w*? zuerst mit der Zeichenfolge cfc456 übereinstimmen, weil w*? , verwendet die reguläre Engine den Ausdruck w+?, um jeweils nur eine Zeichenfolge abzugleichen, und überträgt dann die Kontrolle an das nachfolgende d+, um das nächste Zeichen abzugleichen. Gleichzeitig wird ein Punkt für die Rückkehr hierher aufgezeichnet, wenn die Übereinstimmung vorliegt erfolglos, stimmt erneut überein, was den Backtracking-Punkt darstellt. Da auf w der Quantor * folgt, stellt * 0 bis unzählige Male dar, sodass der erste Wert 0 Mal ist, d Wenn eines der Zeichen c von cfc456n fehlschlägt, wird die Kontrolle an w*? übergeben, um das c von cfc456n abzugleichen Zeichen nach dem anderen und zeichnet den Traceback-Punkt auf und übergibt dann die Kontrolle an d+, um mit f übereinzustimmen, und übergibt dann die Kontrolle an w*?, w*? und zeichnet dann den Traceback-Punkt auf (Zu diesem Zeitpunkt ist das Übereinstimmungsergebnis von w*? cfc) und geben Sie dann die Kontrolle an d+, d+ entspricht 4 und die Übereinstimmung ist erfolgreich. Da der Quantor + ist, ist er 1 bis unzählige Male, also stimmt später überein, stimmt dann mit 5 überein, ist erfolgreich und stimmt dann erneut mit 6 überein. Wenn erfolgreich, dann wird der Vergleichsvorgang fortgesetzt. Das nächste Zeichen ist n und der Vergleich schlägt fehl. Zu diesem Zeitpunkt übergibt d+ die Kontrolle. Da es nach d+ keinen regulären Ausdruck gibt, wird der gesamte reguläre Ausdruck als übereinstimmend deklariert und das Ergebnis ist cfc456, wobei der erste Ergebnissatz 456 ist. Lieber Klassenkamerad, verstehst du das Ergebnis der Frage gerade: Warum ist es 456?

Okay, haben Sie die Prinzipien des Greedy- und Non-Greedy-Matchings aus dem obigen Beispiel verstanden? Verstehen Sie, wann Sie Greedy oder Non-Greedy verwenden müssen, um Ihre Zeichenfolge zu verarbeiten?

In dem Artikel von Niao Ge wurde erwähnt, dass für Ausdrücke und Programme

$reg = "/<script>.*?<\/script>/is"; 
$str = "<script>********</script>"; //长度大于100014 
$ret = preg_repalce($reg, "", $str); //返回NULL
Nach dem Login kopieren

Der Grund dafür ist, dass es zu viele Backtraces gibt, bis der Stapelplatz erschöpft ist und der Stapel explodiert.

再来看个例子。

字符串

$str = '<script>123456</script>';
Nach dem Login kopieren

正则表达式为

$strRegex1 = '%<script>.+<\/script>%'; 
$strRegex2 = '%<script>.+?<\/script>%'; 
$strRegex3 = '%<script>(?:(?!<\/script>).)+<\/script>%';
Nach dem Login kopieren

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

用正则匹配单个字符的详细解析

正则的位置匹配使用详解

Das obige ist der detaillierte Inhalt vonEffizienz der Verwendung regulärer Ausdrücke in PHP Detaillierte Erklärung von Greedy, Non-Greedy und Backtracking (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!