Я пытаюсь найти регулярное выражение, чтобы ловить якоря цитируемыми текстами. Например:
<a href="www.example.com">this is "some quoted anchor text" example</a>
<a href="www.example.com">this is “another” example with different quote type</a>
Я пришел с этим здесь, но он чувствует себя раздутым и не работает должным образом в моей среде php 5.5.9:
https://regex101.com/r/NugIi2/3
Я уверен, что есть лучший способ поймать эти цитируемые якорные тексты.
РЕДАКТИРОВАТЬ: я должен был упомянуть, что мне нужно исправить ошибки на AMP-страницах, которые я получаю из-за якоря текстов с кавычками. Таким образом, никакие манипуляции с DOM в этом случае невозможны. Если быть точным, я использую фильтр the_content worpdress с preg_replace на бэкэнде.
Черт возьми … Буквально через несколько часов мне удалось взломать работающее решение DomDocument! Если есть более чистый способ поддержания точности, я приветствую любого, кто сообщит мне об этом.
Код: (демонстрация)
$html=<<<HTML
<a href="bla">123 "this" is asd</a>
<a href="bla">this should not be captured</a>
<a href="bla">no quotes in anchor text here</a>
<a href="bla">"445 is in quotes"</a>
<a href="bla">asd "blabla" sometimes</a>
<a href="bla">Je commence à avoir mal à la tête</a>
<a href="bla">something with quotes like “blabla” is bad</a>
HTML;
$dom = new DOMDocument;
$html=mb_convert_encoding($html,'HTML-ENTITIES',"UTF-8"); // for multibyte chars
$dom->loadHTML($html,LIBXML_HTML_NODEFDTD); // remove DOCTYPE, but allow <html><body> tags for stability
foreach($dom->getElementsByTagName('a') as $a){
if(preg_match('~["“”]~u',$a->nodeValue)){
$remove[]=$a; // collect the nodes to remove
}
}
foreach($remove as $bad_a){
$bad_a->parentNode->removeChild($bad_a); // remove targeted nodes
}
$result=mb_convert_encoding($dom->saveHTML(),"UTF-8",'HTML-ENTITIES'); // for multibyte chars
echo preg_replace(['~^<html><body>|</body></html>$~','~\R+~'],['',"\n"],$result); // mop up <html> and <body> tags, and consecutive newline characters
Выход:
<a href="bla">this should not be captured</a>
<a href="bla">no quotes in anchor text here</a>
<a href="bla">Je commence à avoir mal à la tête</a>
Или, если вы не хотите связываться со всем этим, вот регулярное выражение с однострочным выражением, которое будет работать так, как задумано:
Код: (демонстрация)
echo preg_replace('~<a[^>]*>.*?["“”].*?</a>\R?~u','',$html);
Других решений пока нет …