我有一些代码在两个文档之间生成差异,随意插入<ins>
和<del>
标记。在大多数情况下,它做得很好,但不时会在脚本,样式和标题标签中插入标签。
有关如何删除 <del>
标记(包括它们之间的文字)的任何想法,删除<ins>
标记(但保留其中的文字作为其中的一部分)原始字符串),但只在这三个标签内? (标题,剧本和风格)。
答案 0 :(得分:2)
不要使用正则表达式来执行此操作;听起来你必须处理很多很多行。 DOMDocument很棒。
$dom = new DOMDocument;
$dom->loadHTML($your_html_string);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//script|//title|//style') as $node) {
foreach ($node->getElementsByTagName('del') as $delNode) {
$node->removeChild($delNode);
}
foreach ($node->getElementsByTagName('ins') as $insNode) {
$node->replaceChild($dom->createTextNode($insNode->nodeValue), $insNode);
}
}
答案 1 :(得分:1)
未经测试,这可能有效,也可能无效:
$str = preg_replace('/(<script.*?>.*?)<del>.*?</del>(.*?</script>)/im', '$1$2', $str);
它试图在&lt; script&gt;中查看...&lt; / script&gt;字符串的块,并替换&lt; del&gt; ...&lt; / del&gt;的任何实例用空字符串。
答案 2 :(得分:0)
以下结果对我来说效果很好:
$tags = array('script', 'title', 'style');
foreach ($tags as $tag) {
$str = preg_replace_callback(
'/(<' . ($tag) . '\b[^>]*>)(.*?)(<\/' . ($tag) . '>)/is',
function($match) {
$replaced = preg_replace(
array(
'/__Delete-Start__.+__Delete-End__/Uis',
'/__Insert-Start__(.+)__Insert-End__/Uis'
),
array(
'',
'$1'
),
$match[2]
);
return ($match[1]) . ($replaced) . ($match[3]);
},
$str
);
}
虽然以下内容并没有最终成为我的解决方案,但它确实让我走得很远,对其他人有用:
$dom = new DOMDocument;
$dom->loadHTML($str);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//script|//title|//style') as $node) {
foreach ($node->getElementsByTagName('del') as $delNode) {
$node->removeChild($delNode);
}
foreach ($node->getElementsByTagName('ins') as $insNode) {
$node->replaceChild($dom->createTextNode($insNode->nodeValue), $insNode);
}
}
$str = (string) $dom->saveXML($dom, LIBXML_NOEMPTYTAG);//$xpath->query('//p')->item(0));
希望这有助于其他人。