2016-12-27 2 views
1

So werde ich mit der Veröffentlichung einige Code beginnen:PHP Regex Gruppierung nicht wie erwartet funktioniert

$output = preg_replace([ 
    '/#(.*?)/i' 
], [ 
    '<h1>$1</h1>' 
], "#Input"); 

Und das endete die Ausgabe:

<h1></h1> 
Input 

In HTML OPT, die Ausgabe I‘ d erreichen möchten ist <h1>Input</h1> von Eingabe #Input, Art von wie Markdown, aber das ist für ein grundlegendes Redaktionssystem.

Ich sah in ein Regex Debugger (here) und die Debug/Stack-Trace war, dass die erste Gruppe war nichts, und die Index-Gruppe war die #.

Nach meinem Wissen sind die einzigen Dinge, die genommen und in Gruppen eingeteilt werden (mir wurde gesagt) (...) 's, und von left -> right die Gruppen sind von $1 -> $x markiert.

Entschuldigung für die überstrapazierten REGEX-Fragen.

Antwort

3

Sie haben ein zusätzliches "?" in deiner Regex.

Versuchen mit:

$output = preg_replace([ 
    '/#(.*)/is' 
], [ 
    '<h1>$1</h1>' 
], "#Input"); 

Da Sie keine Wort-Zeichen passen, wird Groß- und Kleinschreibung nicht viel Sinn machen, so dass Sie schreiben konnte:

$output = preg_replace([ 
    '/#(.*)/s' 
], [ 
    '<h1>$1</h1>' 
], "#Input"); 

Und natürlich, Wenn dies die tatsächliche Lösung wäre, würde ich versuchen, bei meiner Spieldefinition etwas enger zu sein (abhängig von Ihren tatsächlichen Anforderungen). Z.B .:

$output = preg_replace([ 
    '/#([^#\s]+)/s' 
], [ 
    '<h1>$1</h1>' 
], $string); 

Here haben Sie es zu arbeiten. Und here die endgültige Version.

+0

FYI: Der 'i' Modifizierer ist hier redundant, und' .' mit 's' Modifizierer passt * beliebige * Zeichen, was ein Problem sein könnte, wenn der Text die Eingabe eine bereits markierte Zeichenfolge ist. –

+0

Nicht, wie ich diese Regex konstruieren würde, nur auf das unmittelbare Problem konzentrieren und ich nehme an, das ist nicht der vollständige Code für die Frage, aber Ihr Punkt ist genommen. Ich werde daran arbeiten, meine Antwort für zukünftige Besucher zu verbessern. Vielen Dank. – yivi

+0

Ja, Entschuldigung, da es nur ein Teil meiner Code-Basis ist, die den "i" -Operator genauso benötigt wie das "s", entferne ich das "s" von meinem für zukünftige Besucher, so dass es keine schlechte Übung gibt. @ WiktorStribiżew und Antwort OP – Jek

1

Das Problem hier ist, dass die Lazy Dot Matching-Muster am Ende des Musters erscheint, und da es keinen Text entsprechen muss, tut es nicht. Ihre Regex passt ein # und fängt leere Zeichenfolge als Gruppe 1.

Wenn Sie meinen, tatsächlich etwas, Verwendungszweck anzupassen, sagen

'/#(\S+)/' 

eine # anzupassen und erfassen 1 oder mehr Nicht-Leerzeichen Zeichen in Gruppe 1.

Statt \S+, Sie könnten einen eingeschränkteren Muster (wie \w+ für 1 oder mehrere Wort Zeichen verwenden möchten, [^<]+ 1 oder mehr Zeichen übereinstimmen andere als < oder [^\s<]+ übereinstimmen 1+ Zeichen andere als Leerzeichen und <).

Verwandte Themen