我试图用分隔符标签替换仅包含一系列相同字符的段落的所有实例。
我已经使用https://www.phpliveregex.com/来测试代码,将代码直接从那里复制到服务器上的php上,并复制到http://phptester.net/上,但是无法正常工作。
示例:
$test = "<p>Sed nec convallis tortor. Aenean ante diam, aliquet eget porta in, cursus a nibh. Suspendisse eu tempus sem, sit amet malesuada arcu. Nunc condimentum a elit eget elementum. Curabitur id erat et dolor mattis luctus id id massa.</p>
<p>XXXXXXX</p>
<p><em>Nulla vel ligula arcu. Vivamus nec nisi sit amet dui vulputate suscipit.</em></p>
<p><em>Suspendisse finibus lectus ut elit molestie, ornare accumsan lacus accumsan.</em></p>
<p><em>Fusce vel blandit dolor, ac imperdiet purus.</em>.</p>";
echo preg_replace("/<p>(.)\1{3,}<\/p>/i", "<hr />", $test);
这仍将输出<p>XXXXXXX</p>
行,而不是预期的<hr />
行。
有什么想法吗?提示?
答案 0 :(得分:1)
我可以通过将双引号替换为单引号来解决此问题。
echo preg_replace('/<p>(.)\1{3,}<\/p>/i', '<hr />', $test);
如果对模式中的1使用两个\\
,则在对原始代码进行更多测试之后,也将起作用。像这样。
echo preg_replace("/<p>(.)\\1{3,}<\/p>/i", "<hr />", $test);
我认为这是因为使用双引号会将\1
视为转义的1
。在一个转义的反斜杠之前使用两个\\
可以实现\1
的所需指令。这样的事情。我的正则表达式不是很好,但是我认为这是正在发生的事情。您可以通过在模式周围使用单引号来避免所有这些情况。
答案 1 :(得分:1)
正如Joseph_J所指出的那样,问题在于\1
必须传递给正则表达式引擎。这是一个长度为2的字符串,带有两个ASCII字符“ \”和“ 1”。但是在PHP "\[0-9]{1,3}"
中(用双引号引起来)represents only one single character in octal notation。因此"\1"
将是一个长度为1的字符串,由一个带ascii值1的字符组成。这是一个小概述:
source code internal string length
"\1" ascii code 1 1
'\1' \1 2
"\\1" \1 2
'\\1' \1 2
"\134\61" \1 2
如果您还想覆盖换行符(“仅包含一系列相同字符”),则需要pattern modifier来使.
也匹配换行符:
preg_replace('/<p>(.)\1*<\/p>/is', '<hr />', $test);