массив preg_replace: проблема с символами регулярных выражений - PullRequest
1 голос
/ 19 июня 2010

Я хочу заменить группы слов ссылками.

Группы слов определены в многомерном массиве.Будут заменены тысячи терминов, поэтому необходим неиндексированный, легкий и многомерный массив.

Ничто не должно заменяться, если за термином следуют квадратные или квадратные скобки.

Проблема: само регулярное выражение работает нормально, но замена прерывается, когда группы слов включают символы синтаксиса регулярного выражения, такие как +?/ (и т. д. Поэтому мне нужно замаскировать их. Я перепробовал все варианты, которые могу придумать, но это не будет работать для всех случаев. Я не могу замаскировать их в $ text или $ s.

<code><?php

$text = "<html><body><pre>
Replace all foo / bar / baz cases here:
Case 1: Text Foo text.
Case 2: Text 'Foo' Bar text Foo.
Case 3: Text Foobar (2) text.
Case 4: Text Bar & Baz.
Case 5: Text Bar Baz?
Case 6: Text Bar? & Baz?
Case 7: Text Bar-X.

Replace nothing here (text followed by brackets) or [inside square brackets]: 
Case 1: Text Foo (text).
Case 2: Text 'Foo' Bar (text) Foo (text).
Case 3: Text Foobar (2) (text).
Case 4: Text Bar & Baz (text).
Case 5: Text Bar Baz (text).
Case 6: Text Bar? & Baz (text).
Case 7: Text Bar-X (text).
Case 8: [Text Foo]
"; $ s = array (array (" t "=>" Foo "," u "=>" http://www.foo.net"), array ("t" => "'Foo' Bar", "u" =>"http://www.foo.net"), array (" t "=>" Foobar (2) "," u "=>" http://www.foo.net"), array ("t" => "Bar & Baz", "u" => "http://www.foo.net"), array("t" => "Bar Baz?", "u" => "http://www.foo.net"), array (" t "=>" Bar? & Baz? "," u "=>" http://www.foo.net"), array ("t"=> "Bar-X", "u" => "http://www.foo.net")); $ replace = $ text; foreach ($ s as $ i => $ row) {# $ replace = preg_replace ('/ (? ='.preg_quote ($ row ["t"]). '[^ \]] [^ (] + $) \ b'.preg_quote ($ row ["t"]).' \ b / mS ', # $ заменено= preg_replace ('/ (? ='. preg_quote ($ row ["t"], '/').'[^\]][^(]+$)\b'.preg_quote($row["t ")], '/').'\b/mS', # $ replace = preg_replace ('/ (? = \ Q'. $ row ["t"]. '\ E [^ \]] [^ (] +$) \ b \ Q '. $ row ["t"].' \ E \ b / mS ', $ replace = preg_replace (' /(?='.$ row ["t"]. '[^ \]] [^ (]) \ b '. $ row ["t"].' \ b / mS ',' '. $ row ["t"].' ', $ replace);}echo $ replace;?>

Ответы [ 2 ]

1 голос
/ 19 июня 2010

Это должно работать, по крайней мере, в предоставленных тестовых примерах:

$replaced = preg_replace('/([.,\s!^]+)('.preg_quote($row["t"],'/').')([.,\s!$]+)(?!\()/mS',
                           '$1<a href="'.$row["u"].'">$2</a>$3',
                           $replaced);

\b не работает должным образом, когда само совпадение заключено в некоторые границы (как в Foobar (2)), поэтомуВы должны специально предоставить список разрешенных символов.Я быстро положил туда [.,\s!^] и [.,\s!$], вам, вероятно, придется добавить еще несколько разрешенных символов в соответствии с вашими характеристиками (например, -, _?)

0 голосов
/ 19 июня 2010

Я не совсем уверен, что вы пытаетесь сделать, но я видел "разрывы, когда группы слов включают символы синтаксиса регулярных выражений", что заставляет меня думать, что все, что вам нужно сделать, это экранировать эти символы ... т.е. поставить \ перед ними .

EDIT:

Я тоже застрял с этим, но если, если покажешь, что у меня есть, возможно, это поможет тебе:

<code><?php

$text = "<html><body><pre>
Replace all foo / bar / baz cases here:
Case 1: Text Foo text.
Case 2: Text 'Foo' Bar text Foo.
Case 3: Text Foobar (2) text.
Case 4: Text Bar & Baz.
Case 5: Text Bar Baz?
Case 6: Text Bar? & Baz?
Case 7: Text Bar-X.

Replace nothing here (text followed by brackets) or [inside square brackets]: 
Case 1: Text Foo (text).
Case 2: Text 'Foo' Bar (text) Foo (text).
Case 3: Text Foobar (2) (text).
Case 4: Text Bar & Baz (text).
Case 5: Text Bar Baz (text).
Case 6: Text Bar? & Baz (text).
Case 7: Text Bar-X (text).
Case 8: [Text Foo]
"; функция convertRegexChars ($ string) { $ convert = str_replace ("?", "?", $ string); $ convert = str_replace (".", ".", $ convert); $ convert = str_replace ("*", "*", $ convert); $ convert = str_replace ("+", "+", $ convert); вернуть $ конвертированный; } $ s = массив ( массив ("t" => "Foo", "u" => "http://www.foo.net"), array ("t" => "'Foo' Bar", "u" => "http://www.foo.net"), array ("t" => "Foobar (2)", "u" => "http://www.foo.net"), массив ("t" => "Bar & Baz", "u" => "http://www.foo.net"), array ("t" => "Bar Baz?", "u" => "http://www.foo.net"), array ("t" => "Bar? & Baz?", "u" => "http://www.foo.net"), массив ("t" => "Bar-X", "u" => "http://www.foo.net") ); $ replace = convertRegexChars ($ text); foreach ($ s как $ i => $ row) { $ txt = convertRegexChars ($ row ['t']); $ replace = preg_replace ('/(?='.$ txt.' [^ \]] [^ (]) \ b '. $ txt.' \ b / mS ', ''. $ TXT. ', $ Заменен); } echo $ заменен; ?>
...