2016-07-24 17 views
0

Ich habe einige HTML, die mehrere HTML-Kommentare enthält, in jedem Kommentar ist ein Formular. Ich versuche, preg_replace zu verwenden, um diese Kommentare und die darin enthaltenen Formulare durch ein Tag in der Form [CONTACT_FORM_X] zu ersetzen, wobei X die numerische ID des Formulars ist.PHP Regex - ersetzen, aber erhalten numerischen Wert von ersetzten Zeichenfolge

$str = 'blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_1] -->some form goes here<!-- CONTACT FORM END 1 --> blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_2] -->another form goes here<!-- CONTACT FORM END 2 -->'; 

$replace = preg_replace('/<!-- CONTACT FORM START \[CONTACT_FORM_\d\] -->.*<!-- CONTACT FORM END \d -->/', '[CONTACT_FORM_X]', $str); 
echo $replace; 

So:

<!-- CONTACT FORM START [CONTACT_FORM_1] -->some form goes here<!-- CONTACT FORM END 1 --> 

Sollte mit vollständig ersetzt werden sollte [CONTACT_FORM_2]

vollständig mit [CONTACT_FORM_1]

Und ..

<!-- CONTACT FORM START [CONTACT_FORM_2] --> another form goes here<!-- CONTACT FORM END 2 --> 

ersetzt werden ich f Ich betreibe meinen Code über die ich erhalten:

blah blah blah [CONTACT_FORM_X] 

Also meine Fragen sind:

  1. Wie kann ich den Wert von \ d bekommen und diese dann verwenden anstelle von, wo ich zur Zeit X verwenden in mein preg_replace

  2. Mein Code scheint nur eine der Formen anstelle von beiden Vorkommen zu ersetzen. Wie kann ich preg_replace anpassen

Antwort

1

Die preg_replace mehr ersetzt werden, damit alle Vorkommen ersetzen (es ist global). Die .* ist allerdings gierig und passt alles nach der <!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] bis <!-- CONTACT FORM END \d -->. Um einen Wert zu erfassen, verwenden Sie ().

So versuchen:

.*?<!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] -->.*?<!-- CONTACT FORM END \d --> 

oder wenn Sie wollen sicher sein, Sie das gleiche Schließkontakt Formular Rückreferenzierung verwenden passen:

.*?<!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] -->.*?<!-- CONTACT FORM END \1 --> 

Die führenden .*? soll, wenn der vorhergehende Inhalt entfernt werden sollte zurückgehalten werden. Es ist mir unklar, was die Absicht mit diesem Stück ist. Von der Should be replaced entirely with [CONTACT_FORM_2] interpretiere ich als das ist der einzige Inhalt, der bleiben sollte.

Regex Demo: https://regex101.com/r/kS2nK6/1

PHP Verbrauch:

<?php 
$str = 'blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_1] -->some form goes here<!-- CONTACT FORM END 1 --> blah blah blah <!-- CONTACT FORM START [CONTACT_FORM_2] -->another form goes here<!-- CONTACT FORM END 2 -->'; 

$replace = preg_replace('/.*?<!-- CONTACT FORM START \[CONTACT_FORM_(\d)\] -->.*?<!-- CONTACT FORM END \d -->/', '[CONTACT_FORM_$1]', $str); 
echo $replace; 

PHP Demo: https://eval.in/611232

1

Ihr Muster ändern und Ihre Ersatzzeichenfolge wie folgt:

$pattern = '/<!-- CONTACT FORM START \[CONTACT_FORM_(\d+)\] -->.*<!-- CONTACT FORM END \1 -->/'; 
$replace = preg_replace($pattern, '[CONTACT_FORM_$1]', $str); 

Live demo

Wie es

  • Put arbeitet in Klammern beliebigen Text später wieder verwenden wollen. Dies wird erfasste Gruppe genannt. So änderte ich \d zu (\d+) in Ihrem Muster (das + lässt gerade zweistellige + Nummern zu)
  • Um auf die erste eingefangene Gruppe innerhalb des Musters zu verweisen, verwenden Sie \1. Wenn Sie CONTACT FORM END \d zu CONTACT FORM END \1 ändern, wird der Regex-Engine mitgeteilt, dass die zu ersetzende Zeichenfolge stoppt, sobald Sie die END mit derselben Nummer wie in START erreichen. Ohne dies ersetzt der Motor alles bis zuletzt CONTACT FORM END. Deshalb haben Sie nur einen Ersatz bekommen.
  • Verwenden Sie in der Ersetzungszeichenfolge $1, um auf die erste erfasste Gruppe zu verweisen. Aus diesem Grund wird durch die Änderung CONTACT_FORM_X in CONTACT_FORM_$1 die richtige Zahl in die Ersetzungszeichenfolge eingefügt.
+1

@ chris85 Sie haben Recht. Ich habe. Der Ausdruck 'Sollte ersetzt werden 'verweist auf einen Teilstring, der nicht' blah blah blah 'enthält (überprüfe das OP noch einmal) – BeetleJuice

+0

Oh, unklar in diesem Fall. Ich füge meiner Antwort auch noch eine Notiz hinzu. – chris85

Verwandte Themen