我正在尝试获取两个符号或HTML标记之间的文本,然后在该HTML标记中找到所有单词“ sun”并替换为“ moon”,或者将<
替换为<
。例如,我有一个$text
,如下所示:
<body>
<p>
text text sun text text...
<tag> some text here sun some text here </tag>
text text sun text sun text...
<span>
<tag> text here sun text text sun text </tag>
<tag> sun text here sun text sun, sun </tag>
</span>
</p>
</body>
我想找到sun
标记之间的所有<tag>...</tag>
,并将它们替换为moon
,这样结果将是:
<body>
<p>
text text sun text text...
<tag> some text here moon some text here </tag>
text text sun text sun text...
<span>
<tag> text here moon text text moon text </tag>
<tag> moon text here moon text moon, moon </tag>
</span>
</p>
</body>
我尝试了$text = str_replace("sun","moon",$text);
,但这将替换所有插入或删除标记中的匹配项。还尝试了preg_replace("/(<tag>)(.*?)sun(.*?)(<\/tag>)/", "$2 moon $3", $text);
,它无法正常工作。
答案 0 :(得分:2)
如果标记内的文本不包含任何<
,则一种选择是搜索sun
,然后先搜索非<
字符,然后搜索{{ 1}}:
<\/tag>
输出:
$str = "<body>
<p>
text text sun text text...
<tag> some text here sun some text here </tag>
text text sun text sun text...
<span>
<tag> text here sun text text sun text </tag>
<tag> sun text here sun text sun, sun </tag>
</span>
</p>
</body>";
$result = preg_replace("/sun(?=[^<]*<\/tag>)/", "moon", $str);
也就是说,不建议使用正则表达式来解析HTML,除非在最简单的情况下-尽可能使用适当的HTML解析器代替。
答案 1 :(得分:1)
这可能应该通过使用注释中提到的HTML解析器来完成。如果您想使用正则表达式,则可以使用preg_replace_callback
(使用anonymous function> = PHP 5.3)。
omp do
See PHP demo at PhpRun.org-没有匿名功能:
$text = preg_replace_callback('~<tag>\K.*?(?=</tag>)~s', function ($m) {
return preg_replace(['~\bsun\b~i','~<~','~>~'], ["moon","<","&rt;"], $m[0]);
}, $text);
答案 2 :(得分:0)
搜索:(<tag>)(.*?)sun(.*?)(<\/tag>)
替换为:\1moon\4