匹配标签内的标签

Match tags inside tag

我要修改:

<ins><br/> <b>bold</b> <br/><br/> <br/> <br/></ins> <br/> <ins> <br/> </ins>

至:

<ins><br/>NL: <b>bold</b> <br/>NL:<br/>NL: <br/>NL: <br/>NL:</ins> <br/> <ins> <br/>NL: </ins>

(在每个 <ins></ins> 标签内找到 <br/> 并将其更改为 <br/>NL:。忽略 <ins> 之外的 <br/>。此外, <ins> 可能包含各种其他标签)

要做到这一点,我有这个和平的代码:

 $string= preg_replace('~(?:<ins>|(?!^)\G)(.*?)<br\/>~', '[=10=]NL:', $string);

https://regex101.com/r/xI8mW9/4

它会工作得很好,但问题是匹配不会在 </ins> 标签之后结束。如何仅使用 <ins></ins> 标签将 <br/> 替换为 <br/>NL:。它在第一个 <ins>

之后修改每个 <br/>

我也试过模式:

~(<ins>.*?)(?<my_br><br/>)(?!NL:)(.*?</ins>)~

https://regex101.com/r/xI8mW9/15

(在这种情况下,每个 my_br 更改为 $1$2NL:$3) 问题:万一 <ins><br/></ins><br/><ins><br/></ins> 中间 <br/> 受到影响。

尝试按照评论中的建议使用 DOMDocument 进行操作:

    $rendered_diff = "Some<ins>a<br/></ins><br/><ins>b<br/></ins>text";
    $doc = new \DOMDocument();
    $doc->loadHTML($rendered_diff);
    $items = $doc->getElementsByTagName('ins');
    for ($i = 0; $i < $items->length; $i++) {
        foreach ($items->item($i)->childNodes as $node) {
            if ($node->nodeName == 'br') {
                $node->appendData('NL:');
            }
        }
    }
    $doc->saveHTML();
    dd($rendered_diff);

出现错误:

    ERROR: Call to undefined method DOMElement::appendData() 

不知道为什么这种方法不好。

您可以试试下面的代码:

<?php
$rendered_diff = "<br/>Some<ins>a<br/><div>blablaa</div></ins><br/><ins>b<br/></ins>text";
$doc = new \DOMDocument();
$doc->loadHTML($rendered_diff);

$xpath = new DOMXpath($doc);

$items = $doc->getElementsByTagName('ins');
foreach ($xpath->query("//ins/br") as $br) {
    $text = $doc->createTextNode('NS:');
    $br->parentNode->insertBefore( $text, $br->nextSibling);
}

echo $doc->saveXML();

输出如下:

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><br/>Some<ins>a<br/>NS:<div>blablaa</div></ins><br/><ins>b<br/>NS:</ins>text</body></html>

这似乎解决了问题。

请注意,我稍微修改了您的初始 XML,以测试您的

Ignore <br/> outside <ins>

状况。见第一条<br/>

回答您的问题

Have no idea why this approach is bad.

你的方法不好,因为this,把它和我放在上面的代码比较一下:后者看起来不是更干净吗?此外,它使用 XPath,您可以创建更复杂的查询来匹配某些元素,而不仅仅是 <ins>

中的 <br>