preg_replace“gotcha”具有替换值转义

时间:2013-01-03 16:05:31

标签: php preg-replace

我正在运行一个我不一定控制的内容的preg_replace,并且我遇到了包含货币值(即$1.00)等内容的替换值的问题。不可否认,这是一个在其他问题中已经解决的常见问题。我发现的最接近的解决方案是:

http://www.procata.com/blog/archives/2005/11/13/two-preg_replace-escaping-gotchas/

我的问题更复杂,因为替换值不是我可以提前逃脱的东西,至少不是我能看到的方式。这是我的preg代码:

$body = preg_replace('/<special_tag id="'.$tagID.'">(.*?)<\/special_tag>/','$1',$body);

正如您所看到的,我正在捕获设置自定义标记内的所有内容,并删除周围的开始和结束标记,但保留内部的内容。然而,替换'$1'不适用于所需的转义,因此恰好在替换值中的货币值将被错误地终止。

我有没有想过这个替代品?我还可以使用其他东西来删除我的特殊标签,记住它必须考虑该特定标签的唯一ID吗?

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

可能没有任何“陷阱”的DOM解决方案。

假设这个HTML:

$html = <<< HTML
<html>
    <body>
        <special_tag id="foo">
            <p>Some content</p>
            <p>Some more content</p>
        </special_tag>
    </body>
</html>
HTML;

你拉起了special_tag的孩子,然后删除了special_tag:

// create DOMDocument, suppress parsing errors
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();

// get special_tag with id foo
$xpath = new DOMXPath($dom);
$foo = $xpath->query('//special_tag[@id="foo"]')->item(0);

// move all children before special_tag
while ($foo->childNodes->length > 0) {
    $foo->parentNode->insertBefore($foo->childNodes->item(0));
}

// remove now empty special_tag
$foo->parentNode->removeChild($foo);

// output
echo $dom->saveHTML($dom->documentElement);

会产生类似

的结果
<html><body>
    <p>Some content</p>
        <p>Some more content</p>
    </body></html>

答案 1 :(得分:0)

建议不要使用Regex解析XML / HTML。请改用 DOM 解析器。