2013-09-09 6 views
0

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

Вот что я в настоящее время:

$this->parsed = preg_replace('/\b(?<!\[)('.preg_quote($word).')\b/','[$1['.implode(",",array_unique($types)).']]',$this->parsed); 

Где $ слово может быть один из следующих "Burkely Mayfair Trunk" или "хобота".

Было бы заменить предложение

This Burkely Mayfair Trunk is pretty nice

для

This [Burkely Mayfair [Trunk[productname]][productname]] is pretty nice

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

This [Burkely Mayfair Trunk[productname]] is pretty nice

Поскольку он заменяет в порядке наибольшего строки наименьшему строки, меньшие строки и/или двойные вхождения словных частей не должны заменяться в уже представленном заштрихованная часть строки. Он работает, когда это первая часть строки.

Когда я пытаюсь сделать динамический lookbehind, он дает следующую ошибку: «Ошибка компиляции: утверждение lookbehind не является фиксированной длиной при смещении 11». И я понятия не имею, как это исправить.

Любой, у кого есть идеи?

+0

В большинстве реализаций GREP Lookbehinds должен иметь фиксированную длину. Что ты пробовал? (Также: Почему замена «от самой большой до самой маленькой» является проблемой?) – usr2564301

+0

Позвольте мне перефразировать этот вопрос: вы хотите совместить определенное слово или фразу, только если она не заключена в квадратные скобки, а затем скобка? –

+0

Jongware: замена от самого большого к самому маленькому не является проблемой, но самые маленькие строки могут содержать части, которые уже присутствуют в больших строках и, следовательно, больше не должны быть заключены в скобки, потому что большая строка уже заключена в квадратные скобки. @Sniffer Точно, см. Мое объяснение Jongware – riekelt

ответ

0

После следующего утра игры с регулярным выражением я придумал довольно грязное решение, которое не является гибким вообще, но работает для моего прецедента.

$this->parsed = preg_replace('/\b(?!\[(|((\w+)(\s|\.))|((\w+)(\s|\.)(\w+)(\s|\.))))('.preg_quote($word).')(?!(((\s|\.)(\w+))|((\s|\.)(\w+)(\s|\.)(\w+))|)\[)\b/s','[$10['.implode(",",array_unique($types)).']]',$this->parsed); 

Что в основном делает это проверить скобки без слов, 1 слово или 2 слов впереди или позади него в сочетании с указанным ключевым словом.

Тем не менее, было бы здорово услышать, есть ли у кого-то лучшее решение.