2016-02-11 10 views
7

Ich habe den ganzen Morgen lang versucht, die Regex richtig zu machen, und ich habe die Wand getroffen. In der folgenden Zeichenfolge möchte ich jeden folgenden Schrägstrich, der .com/<first_word> mit Ausnahme von allen /nach die URL folgt.Übereinstimmungen eines bestimmten Charakters nach einem positiven Lookbehind

$string = "http://example.com/foo/12/jacket Input/Output"; 
    match------------------------^--^ 

Die Länge der Wörter zwischen den Schrägstrichen sollte keine Rolle spielen.

Regex: (?<=.com\/\w)(\/) Ergebnisse:

$string = "http://example.com/foo/12/jacket Input/Output"; // no match 
$string = "http://example.com/f/12/jacket Input/Output"; 
    matches--------------------^ 

Regex: (?<=\/\w)(\/) Ergebnisse:

$string = "http://example.com/foo/20/jacket Input/O/utput"; // misses the /'s in the URL 
    matches----------------------------------------^ 
$string = "http://example.com/f/2/jacket Input/O/utput"; // don't want the match between Input/Output 
    matches--------------------^-^--------------^      

Da das Lookbehind kann keine Modifikatoren haben und muss eine Länge von Null Behauptung, die ich frage mich, ob ich gerade haben auf den falschen Weg gestolpert und sollte eine andere Regex-Kombination suchen.

Ist der positive Blick der richtige Weg, dies zu tun? Oder vermisse ich etwas anderes als viel Kaffee?

HINWEIS: getaggt mit PHP weil die Regex in jede der preg_* Funktionen funktionieren sollte.

+2

The'preg_match' Funktion gibt ein Spiel. Sie sagen, Sie müssen alle Zeichen übereinstimmen, die nach einem Muster vorhanden sind. Sie sollten 'preg_match_all' verwenden. –

+0

Ich habe immer noch den Eindruck, dass es ein XY-Problem ist. Was versuchst du zu erreichen? Warum passen diese Schrägstriche? Sie könnten die URL url_parse und dann tun, was Sie wollen. Explodieren, z.B. –

+0

Nein, es ist kein XY-Problem @ WiktorStribiżew, da die Regex in * any * der 'preg_ *' - Funktionen funktionieren sollte. –

Antwort

3

Wenn Sie preg_replace dann diese regex sollte verwenden möchten arbeiten:

$re = '~(?:^.*?\.com/|(?<!^)\G)[^/\h]*\K/~'; 
$str = "http://example.com/foo/12/jacket Input/Output"; 
echo preg_replace($re, '|', $str); 
//=> http://example.com/foo|12|jacket Input/Output 

So jede / durch eine | nach der ersten Ersetzung / erscheint nach dem Start .com.

Negative Lookbehind (?<!^) wird benötigt, um zu vermeiden, eine Zeichenfolge zu ersetzen, ohne .com wie /foo/bar/baz/abcd zu starten.

RegEx Demo

+0

Das Problem damit ist, dass du es bist Ersetzen Sie die '/' im Teil der Zeichenfolge durch 'Input/Output' –

+0

Es sollte nur die Schrägstriche * nach * foo sein, aber nicht in irgendetwas nicht in der URL –

+0

Es gibt eine URL in der Zeichenfolge, sowie einige andere Daten. Die Schrägstriche in den anderen Daten sollten nicht betroffen sein. –

3

Verwenden Sie \K hier zusammen mit \G .grab die groups.

^.*?\.com\/\w+\K|\G(\/)\w+\K 

Siehe Demo.

https://regex101.com/r/aT3kG2/6

$re = "/^.*?\\.com\\/\\w+\\K|\\G(\\/)\\w+\\K/m"; 
$str = "http://example.com/foo/12/jacket Input/Output"; 

preg_match_all($re, $str, $matches); 

Replace

$re = "/^.*?\\.com\\/\\w+\\K|\\G(\\/)\\w+\\K/m"; 
$str = "http://example.com/foo/12/jacket Input/Output"; 
$subst = "|"; 

$result = preg_replace($re, $subst, $str); 
+0

Aus irgendeinem Grund funktioniert dies nicht im Zusammenhang mit 'preg_match()' –

+0

OK - 'preg_match_all()' funktioniert aber andere 'preg ....' Funktionen scheitern - wie 'preg_replace()'. –

+0

@JayBlanchard das einzige Problem mit Ersatz ist ein zusätzlicher Ersatz wird am Ende passiert .... denke, dass separat behandelt werden muss – vks