Сопоставлять слова только вне оператора HTML с регулярным выражением - PullRequest
1 голос
/ 23 декабря 2009

То, чего я хочу достичь с помощью приведенного ниже кода: сопоставить указанное слово без учета регистра и только один раз в тексте и заменить его ссылкой.

У меня есть следующий preg_match, чтобы соответствовать слову 'foo' в строке:

if (preg_match("/\bfoo\b/i", $text, $results, PREG_OFFSET_CAPTURE)) { 
  // substr_replace the word 'foo' for a link <a href.. 
}

Нет проблем для текста без HTML, но представьте следующий текст с HTML:

Lorem ipsum dolor sit amet, <a href="/foo-bar/" title="foo bar">some other foo link</a> consectetur adipiscing elit foo bar.

В этом случае в текущей ссылке будет новая ссылка, потому что в href-part будет совпадение с foo (та же проблема для заголовка и имени).

Как можно изменить шаблон, чтобы он соответствовал только 'foo' вне оператора HTML?

Ответы [ 2 ]

3 голосов
/ 23 декабря 2009

Не анализировать HTML с регулярными выражениями . Вместо этого используйте XPath . PHP может легко использовать его .

Выражение XPath для того, что вы хотите, довольно просто. Предполагая, что тег, который вы хотите найти внутри - div, это то, что вы хотите:

//div/text()[contains(.,'foo')]

Если у вас есть текстовый узел, вы можете запустить на нем регулярное выражение, не опасаясь, что в нем будут какие-либо HTML-теги.

0 голосов
/ 23 декабря 2009

Вы можете посчитать количество открывающих и закрывающих скобок, которые встречались до сих пор. Если они различаются, это означает, что вы открыли скобку, еще не встретив закрывающую, что означает, что вы в данный момент находитесь внутри тега HTML.

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

...