我正在尝试匹配可能出现在多行上的字符串.它以特定字符串开头和结尾:
{a}some string can be multiple lines {/a}
我可以抓住之间的一切{a}
,并{/a}
用正则表达式?好像是.不匹配新行,但我尝试了以下没有运气:
$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/', 'X', $template, -1, $count ); echo $count; // prints 0
它匹配 .或\n当他们独立时,但不在一起!
使用s
修饰符:
$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/s', 'X', $template, -1, $count ); // ^ echo $count;
我认为你有更多的问题,而不仅仅是不匹配换行符的点,但让我先从格式化建议开始.您可以使用任何标点字符作为正则表达式分隔符,而不仅仅是斜杠('/').如果使用其他字符,则不必在正则表达式中转义斜杠.我知道'%'在PHPers中很受欢迎; 这会使你的模式参数:
'%\{a\}([.\n]+)\{/a\}%'
现在,正则表达式无法按预期工作的原因是因为当点出现在字符类(方括号)中时,点会失去其特殊含义 - 因此[.\n]
只需匹配点或换行符.你在寻找什么(?:.|\n)
,但我建议匹配回车和换行:
'%\{a\}((?:.|[\r\n])+)\{/a\}%'
那是因为"newline"这个词可以指Unix风格的"\n",Windows风格的"\ r \n"或旧版Mac风格的"\ r".任何给定的网页可以包含任何这些或两种或更多种风格的混合; "\n"和"\ r \n"的混合很常见.但是使用/ s模式(也称为单行或DOTALL模式),您无需担心:
'%\{a\}(.+)\{/a\}%s'
然而,原始的正则表达式还存在另一个问题,即仍然存在于此:+
贪婪.这意味着,如果{a}...{/a}
文本中有多个序列,则第一次应用正则表达式时,它将匹配所有这些序列,从第一个{a}
到最后一个{/a}
.解决这个问题的最简单方法是+
通过添加问号来使不合格(又称"懒惰"或"不情愿"):
'%\{a\}(.+?)\{/a\}%s'
最后,我不知道在你的模式参数的开头引用之前该怎么做'$'.我不做PHP,但这看起来像是一个语法错误.如果有人可以在这件事上教育我,我会很感激.