【发布时间】:2019-07-26 12:28:56
【问题描述】:
对于我的 CMS,如果 [?][/?] 标记之间包含字符串 %empty%,我需要替换多行内容,如果找不到 %empty% 标记,则保持不变。
$a='
[?]<h1>%empty%</h1>
<p>text</p>
[/?]
text
[?]<h1>%empty%</h1>
<p>text</p>
[/?]
text';
$r= preg_replace (
'/(\[\?\]).*?%empty%.*?(\[\/\?\])/s',
"REPLACED",
$a ) ;
echo $r;
正确的结果:
REPLACED
text
REPLACED
text
它几乎适用于所有组合,除非 first 行不匹配。在这种情况下,将替换第一个 [?] 和最后一个 [/?] 之间的所有内容
$a='
[?]<h1>%!empty%</h1>
<p>text</p>
[/?]
text
[?]<h1>%empty%</h1>
<p>text</p>
[/?]
text';
Wrong result:
REPLACED
text
Expected:
[?]
<h1>%!empty%</h1>
<p>test</p>
[/?]
text
REPLACED
text
我同时使用不贪婪和“懒惰”的常规异常,结果相同。我需要在正则表达式中明确定义第二个 [/?],但没有成功。
【问题讨论】:
-
问题是即使是非贪心搜索也能从左到右工作。看到
[?]后,贪婪说“我可以从这里采取最长的延续”,非贪婪说“最短”,但都没有说“有没有以后的[?]我可以从这里开始?”因此,您需要将.*替换为与下一个[?]不匹配的东西,这不是微不足道的,但应该是可能的。 -
如果
[或]在文本中被允许但必须被转义,用([^][]|\\\[|\\\])替换.*会起作用。演示:regex101.com/r/Cgx19h/2 但是,如果您通常允许使用方括号,我不确定该怎么做。 -
也许使用 2 次回火的贪婪令牌 regex101.com/r/2UWj23/1
-
@Axis 我不知道出了什么问题 - regex101.com/r/Cgx19h/6
标签: php regex regex-negation