У меня есть следующее регулярное выражение, которое выполняет отрицательный прогноз.
/\b(\w+)\b(?![^<]*</{0,1}(a|script|link|img)>)/gsmi
То, что я хочу сделать, это сопоставить весь текст, включая html, кроме a, script, link и img. Теперь проблема возникает, когда используется тег img.
Тег изображения не имеет закрывающего тега, поэтому выражение не исключает теги img.
<p>This is a sample text <a href="#">with</a> a link and an image <img src="" alt="" /> and so on</p>
Регулярное выражение не должно совпадать с якорем (даже между открывающим и закрывающим тегом) и не должно совпадать с img.
Я думаю, что я почти там, но я не могу заставить его работать должным образом. Это то, что я тоже пробовал:
/\b(\w+)\b(?![^<]*</{0,1}(a|script|link)>)(?![^\<img]*>)/gsmi
Каким-то образом последний будет работать (только для тега img), если в теге img нет «i», «m» или «g». Когда вы добавляете что-то вроде высоты = это не будет совпадать.
редактировать
Цель состоит в том, чтобы извлечь все слова из текста, кроме тех, которые находятся между тегами привязки и изображения, и может быть вероятность того, что в нем вообще не будет HTML
Я знаю, что вы попросили регулярное выражение, но вот решение, использующее то, что не вызвать Ктулху.
$html = <<<'HTML'
<p>This is a <em>sample</em> text <a href="#">with</a>
a link and an image <img src="" alt="" /> and so on</p>
HTML;
$dom = new DOMDocument();
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
foreach($xpath->query('//a | //link | //script | //img') as $node) {
$node->parentNode->removeChild($node);
}
echo $dom->saveHTML();
<p>This is a <em>sample</em> text
a link and an image and so on</p>
Я рекомендую рассмотреть это как вариант.
Других решений пока нет …