Лучшим заголовком для вопроса может быть: "Соответствует элементу DIV
, содержащему определенную подстроку." Сначала нужно сказать, что регулярное выражение - не лучший инструмент для этой работы. Было бы намного лучше использовать анализатор HTML для анализа разметки, а затем искать содержимое каждого элемента DIV
для поиска нужной подстроки. Тем не менее, поскольку вы не хотите больше знать о том, как использовать регулярные выражения для сопоставления с вещами, которые не являются чем-то другим, следующее описывает ограниченный способ сделать это с помощью регулярных выражений.
Как правильно указывает Догберт, этот вопрос действительно является дубликатом Регулярного выражения для соответствия строке, не содержащей слова? . Тем не менее, я вижу, что вы рассмотрели этот вопрос, но вам необходимо знать, как применить эту технику к подшаблону.
Чтобы сопоставить часть строки (подшаблон), которая не включает в себя определенное слово (или слова), вам необходимо применить проверку на отрицательное предпросмотр перед каждым и каждым символом. Вот как это делается для текста между открывающими и закрывающими тегами DIV
. Обратите внимание, что при использовании только одного регулярного выражения, поскольку элементы DIV
могут быть вложенными, разумно найти "HELLO"
в «самом внутреннем» из вложенных элементов DIV
.
Псевдокод:
- Соответствует открывающему тегу
DIV
.
- Ленивое совпадение с нулем или более символов, каждый из которых не является началом
<div
или </div
.
- Как только искомая строка:
"HELLO"
найдена, продолжайте и сопоставьте ее.
- Продолжить (жадно) сопоставляя ноль или более символов, каждый из которых не является началом
<div
или </div
.
- Соответствует закрывающему тегу
</div>
.
Обратите внимание, что для сопоставления только с "самым внутренним" содержимым DIV
необходимо исключить <DIV
и </DIV
при сканировании содержимого элемента по одному символу за раз. Вот соответствующее регулярное выражение в виде проверенной функции PHP:
// Find an innermost DIV element containing the string "HELLO".
function p1($text) {
$re = '% # Match innermost DIV element containing "HELLO"
<div[^>]*> # DIV element start tag.
(?: # Group to match contents up to "HELLO".
(?!</?div\b) # Assert this char is not start of DIV tag.
. # Safe to match this non-DIV-tag char.
)*? # Lazily match contents one chara at a time.
\bhello\b # Match target "HELLO" word inside DIV.
(?: # Group to match content following "HELLO".
(?!</?div\b) # Assert this char is not start of DIV tag.
. # Safe to match this non-DIV-tag char.
)* # Greedily match contents one chara at a time.
</div> # DIV element end tag.
%six';
if (preg_match($re, $text, $matches)) {
// Match found.
return $matches[0];
} else {
// No match found
return 'no-match';
}
}
Эта функция будет правильно соответствовать желаемому элементу DIV ваших следующих тестовых данных:
<div>Bye.</div><div>Hello!</div>
Он также будет правильно находить "HELLO" внутри самых вложенных элементов DIV:
<div>
<div>
Hello world!
</div>
</div>
Но, как указывалось ранее, NOT найдет строку "HELLO", расположенную внутри не внутренних вложенных элементов DIV, так:
<div>
Hello,
<div>
world!
</div>
</div>
Это гораздо более сложное решение.
Есть много случаев, когда это решение может дать сбой. Снова. Я рекомендую использовать анализатор HTML.