Регулярное выражение: заменить только в определенном контексте - PullRequest
2 голосов
/ 25 марта 2010

В тексте я хотел бы заменить все вхождения $word на [$word]($word) (чтобы создать ссылку в Markdown), но только если ее еще нет в ссылке. Пример:

[$word homepage](http://w00tw00t.org)

должно не стать

[[$word]($word) homepage](http://w00tw00t.org).

Таким образом, мне нужно проверить, находится ли $ word где-то между [и], и заменить только, если это не так.

Можете ли вы придумать для этого команду preg_replace?

Ответы [ 2 ]

3 голосов
/ 25 марта 2010

Это не так просто, как вы думаете. Предыдущие ответы потерпят неудачу во многих ситуациях. Вот тот, который должен заменить каждое слово $, которое уже не находится внутри []:

$text = preg_replace('/\G((?:[^\[]|\[[^\]]*\])*?)('.$word.')/', '$1[$2]($2)', $text)

Если $ word содержит специальные символы регулярного выражения, вы можете захотеть preg_quote it.

Пример

$text = 'aa foo bb [foo bar](http://example.com) cc foo dd';
$word = 'foo';
$text = preg_replace('/\G((?:[^\[]|\[[^\]]*\])*?)('.$word.')/', '$1[$2]($2)', $text);
echo $text;

Выход:

aa [foo](foo) bb [foo bar](http://example.com) cc [foo](foo) dd

0 голосов
/ 25 марта 2010

я думаю

"~ $ слово (?!. *?]) ~"

 "~$word(?=[^\[\]]*(\[|$))~"

, например

$src = "aa foo [ bbb foo xyz ] cc foo dd";
$word = "foo";
print preg_replace("~$word(?=[^\[\]]*(\[|$))~", "[FOO](bar)", $src);
...