2009-05-14 15 views
0

Demo:php nicht gierige regex Problem

$str = 'bcs >Hello >If see below!'; 
$repstr = preg_replace('/>[A-Z0-9].*?see below[^,\.<]*/','',$str); 
echo $repstr; 

Was ich dieses kleine Programm ausgeben will, ist „bcs> Hallo“, aber in Wirklichkeit ist es nur „bcs“

Was mit meinem Muster falsch ?

+0

Ihre Frage ergibt keinen Sinn mit Ihrem Code-Snippet. Ihre Aussage ersetzt das Muster durch nichts. Ihre Antwort schlägt vor, dass Sie es durch etwas ersetzen möchten. – cletus

+0

Das Programm macht, was Sie gefragt haben, zu tun. Es ist nicht klar, was du bekommen willst. Gib ein anderes Beispiel. – jbasko

+0

Es ist etwas mit nicht-gierigen Regex, ich denke, es ist ziemlich klar, warum nicht? – omg

Antwort

0

Warum nicht Sie es wie folgt schreiben:

$str = 'bcs >Hello >If see below!'; 
$repstr = preg_replace('/>If see below[^,\.<]*/','',$str); 
echo $repstr; 
+0

weil Was ich will ist das erste großgeschriebene Zeichen oder Nummer nach> – omg

0

Dies könnte eine gute Alternative zu dem, was Sie haben. Das Problem mit Ihrer Regexp ist, dass Sie, anstatt auszuwählen, was Sie wollen, Sie wählen, was Sie nicht wollen, und ersetzen Sie das durch eine leere Zeichenfolge. Der beste Ansatz, meiner Meinung nach, ist die Auswahl, was Sie wollen, das ist, was der Code unten tut. Was Sie am Ende haben, ist, was mit dem ersten Sub-Muster übereinstimmt, ansonsten erhalten Sie Ihre Saite zurück.

$str = 'bcs >Hello >If see below!'; 
$repstr = preg_replace('/^([\w]+ >[\w]+).*?see below.*?$/i', '$1', $str); 
var_dump($repstr); 

Ich hoffe, das hilft.

+0

Sorry, was ich tun möchte, ist genau zu ersetzen: Start von "zuerst Großbuchstaben oder Zahl nach>" Ende mit "siehe unten [^, \. < ] * " zu leeren. – omg

4

Ich denke, das Problem ist, dass Sie falsch interpretieren, wie ein nicht-gieriger Quantifikator handelt. Sobald es in Betrieb ist, hört es früher auf als es sonst der Fall wäre. Aber es ist nicht bewusst von dem, was davor kommt (oder möglicherweise der Text, der später kommt). Es geht nur um seine aktuelle Position. Daher Sie der reguläre Ausdruck geschrieben wird alle überein:

">Hello >If see below!" 

Mal sehen, wie das funktioniert:

/>[A-Z0-9].*?see below[^,\.<]*/ 

Die Regex zuerst für „>“ in „bcs sehen> Hallo> Wenn unten sehen! ", und findet den ersten, der gleich vor" Hello "ist. Ok, lassen Sie sich den nächsten Teil des Ausdrucks überprüfen:

[A-Z0-9] 

Das nächste Zeichen ist ein H, die das Muster entspricht [A-Z0-9]. Immer noch gut! Next:

.*? 

Jetzt passen wir alle nicht Newline Zeichen, bis wir auf die erste Instanz erhalten die verbleibenden Ausdrücke passen „siehe unten [^ ,. <] *“. Wenn wir nur einen reinen gierigen Quantifizierer verwendet hätten, könnten wir mehrere Fälle von "siehe unten [^. <] *" abgleichen, bis wir den letzten möglichen Treffer gefunden hätten. (Wenn also Ihre Zeichenfolge fortgesetzt wurde und anderer Text mit diesem Muster übereinstimmt, hätte dies auch erfasst.) Der nicht-gierige Quantifizierer bedeutet nicht, dass Ihr gesamtes Muster die kleinstmögliche Übereinstimmung von ist alle möglichen Übereinstimmungen in der Zeichenfolge. Es bestimmt nur, wie dieses bestimmte Zeichen funktioniert.

Sie könnten die folgenden Muster versuchen wollen, dann:

/>[A-Z0-9][^>]*?see below[^,\.<]*/ 

Hoffentlich klären it up!

+0

Vielen Dank für Ihre Antwort, aber das wird nicht für mich funktionieren. Weil es in diesem Fall nicht funktioniert: $ str = 'bcs <> Hallo <> Wenn
siehe unten!'; Ich möchte 'bcs <> Hallo <' nach der Verarbeitung haben. – omg

+0

Sie könnten versuchen, den Kontext Ihrer Frage genauer auszuarbeiten, und Sie erhalten möglicherweise bessere Antworten. – patjbs

+0

Hier ist die Lösung: $ str = 'bcs <> Hallo <> Wenn

siehe unten!'; $ repstr = preg_replace ('/> [A-Z0-9] [^>] * (> [^ A-Z0-9] *) * siehe unten [^, \. <] * /', '', $ str); echo $ repstr; Vielen Dank für Ihre Aufmerksamkeit auf dieses Problem :) – omg