提问人:kim li 提问时间:4/15/2023 最后编辑:bobble bubblekim li 更新时间:4/25/2023 访问量:40
奇怪的PHP preg_replace结果
Weird PHP preg_replace result
问:
$pedit =<<<head
<div class="item"><div var="i_name_10">white gold</div> <div var="i_price_10">$5.99</div></div>
head;
$pedit = preg_replace("/(<.*var=\"i_name_10\".*>)(.*)(<\/.*?>\s*)/","$1"."aaa"."$3",str_replace("> <","><",$pedit));
结果:
white gold
$5.99
aaa
预期结果是
aaa
$5.99
当我在“白金”div 之后的换行符后放一个换行符或在图案后放一个 U 时,它就会按预期工作。但是,如果字符串重复并且更长,则这些解决方案似乎有问题或不干净。请帮忙!/U
白金替换为 AAA,而不是在末尾附加 AAA。
预期结果是
aaa
$5.99
答:
问题解释
默认情况下,正则表达式匹配将尽可能贪婪。这意味着第一个捕获组中的部分将比您预期的匹配更多。.*
对于 ,这匹配:<.*var=\"i_name_10\"
<div class="item"><div var="i_name_10"
然后我们有剩下的字符串:
>white gold</div> <div var="i_price_10">$5.99</div></div>
正则表达式的下一部分是 ,这可以吞噬所有:.*>
>white gold</div> <div var="i_price_10">$5.99</div>
因为下一部分,不能匹配任何东西,因为量词表示 0 或更多。(.*)
*
我们现在有:
</div>
哪个匹配。(<\/.*?>\s*)
因此,我们的捕获组是
捕获 | 结果 |
---|---|
(<.*var=\"i_name_10\".*>) |
<div class="item"><div var="i_name_10">white gold</div> <div var="i_price_10">$5.99</div></div> |
(.*) |
|
(<\/.*?>\s*) |
</div> |
这就是为什么当您替换为 时,您将得到:"$1"."aaa"."$3"
<!-- $1 -->
<div class="item"><div var="i_name_10">white gold</div> <div var="i_price_10">$5.99</div></div>
<!-- /$1 -->
aaa
<!-- $3 -->
</div>
<!-- /$3 -->
溶液
但是,如果字符串重复并且更长,则这些解决方案似乎有问题或不干净
很难辨别你在这里所说的“字符串重复”是什么意思,哪个字符串重复?整个事情?同样对于“而且它更长”,你说的“它”具体是什么意思?
但是,不管这些注意事项如何,您似乎正在替换 HTML。因此,您可以使用最初提到的标志,或者可以在第一个捕获组中使用某种“手动”不贪婪,例如:<div var="i_name_10">white gold</div>
U
"/(<[^>]+var=\"i_name_10\"[^>]*>)(.*)(<\/[^>]+?>\s*)/"
我们使用表达式来声明除了 之外的任何字符都可以,因此我们只在元素内部匹配,而不匹配“外部”元素。我们还使用 1 个或多个量词 () 而不是 0 或更多 (),因为 HTML 需要元素开头和结束标记中的元素名称。这减少了任何意外的机会。[^>]
>
+
*
与其编写一个你自己在一夜睡眠后无法读取或修改的正则表达式,更不用说其他人了,不如使用专门设计用于解析和修改你所拥有的数据的工具。
$pedit =<<<'head'
<div class="item"><div var="i_name_10">white gold</div> <div var="i_price_10">$5.99</div></div>
head;
$d = new DOMDocument();
$d->loadHTML($pedit, LIBXML_HTML_NOIMPLIED);
// search for elements with the defined attribute, modify results
$xpath = new DOMXPath($d);
foreach($xpath->query('//div[@var="i_name_10"]') as $node) {
$node->nodeValue = 'aaa';
}
var_dump($d->saveHTML($d->documentElement));
输出:
string(88) "<div class="item"><div var="i_name_10">aaa</div> <div var="i_price_10">$5.99</div></div>"
评论