我认为您遇到的问题不仅仅是点不匹配换行符,但让我从格式建议开始。您可以使用几乎任何标点符号作为正则表达式分隔符,而不仅仅是斜杠 ('/')。如果您使用另一个字符,则不必在正则表达式中转义斜杠。我知道 '%' 在 PHPers 中很流行;这将使您的模式论点:
'%\{a\}([.\n]+)\{/a\}%'
现在,正则表达式没有按您的预期工作的原因是,当点出现在字符类(方括号)中时,它失去了它的特殊含义——所以[.\n]
只匹配一个点或换行符。您正在寻找的是(?:.|\n)
,但我会建议匹配回车符和换行符:
'%\{a\}((?:.|[\r\n])+)\{/a\}%'
这是因为“换行符”这个词可以指代 Unix 样式的“\n”、Windows 样式的“\r\n”或旧 Mac 样式的“\r”。任何给定的网页可能包含其中任何一种或两种或多种样式的混合;"\n" 和 "\r\n" 的混合很常见。但是使用 /s 模式(也称为单行或 DOTALL 模式),您无需担心:
'%\{a\}(.+)\{/a\}%s'
但是,原始正则表达式存在另一个问题,它仍然存在于这个问题中:+
贪婪。这意味着,如果文本中有多个{a}...{/a}
序列,则第一次应用正则表达式时,它将匹配所有序列,从 first{a}
到 last {/a}
。+
解决这个问题的最简单方法是通过附加一个问号来使不贪心(又名“懒惰”或“不情愿”):
'%\{a\}(.+?)\{/a\}%s'
最后,我不知道在你的模式参数的开头引号之前如何理解'$'。我不做 PHP,但这对我来说似乎是一个语法错误。如果有人可以在这件事上教育我,我将不胜感激。