PHP preg_match 多行字符串的正则表达式

Regex for a multiline string with PHP preg_match

我正在尝试为多行字符串构建一个模式,该模式必须以 <?phpwhitespace + <?phpNOT[=26= 开头] 以 ?>?> + whitespace.

结尾

我的尝试是/^\s?<\?php.*[^>]\s?$/s,但没有成功。还尝试了负前瞻 - 没用。

有什么想法吗? 提前致谢。

您可以使用

(?s)^\s*<\?php(?!.*\?>\s*$).*+$

demo

正则表达式解释:

  • (?s) - 为 . 的整个模式启用单行模式以匹配换行符
  • ^ - 字符串开始
  • \s* - 可选空格,0 次或多次重复
  • <\?php - 文字 <?php
  • (?!.*\?>\s*$) - 前瞻检查字符串是否不以 ?>whitespace
  • 结尾
  • .*+$ - 不回溯任何字符直到字符串末尾的匹配。

possessive quantifier(在 .*+ 中)使我们能够一次性使用字符,并且永远不会回来寻找可能的排列。

Possessive quantifiers are a way to prevent the regex engine from trying all permutations. This is primarily useful for performance reasons.

然后我们不使用明确的 SKIP-FAIL 动词。

在 PHP 中,您可以使用此正则表达式:

'/^\s*<\?php(?:.(?!\?>\s*$))*$/s'

RegEx Demo

  • ^\s*<\?php 匹配行开头的可选空格和文字 <?php
  • (?:.(?!\?>\s*$))* 将使用否定先行匹配不以 ?>whitespace* 结尾的任何 0 个或多个字符。

更新: 为了提高效率,此 PCRE 正则表达式的执行速度将快于前一个:

'/^\s*<\?php(?>.*\?>\s*$(*SKIP)(*F)|.*+$)/s'

RegEx Demo 2

  • (*FAIL) 表现得像一个失败的否定断言,是 (?!)
  • 的同义词
  • (*SKIP) 定义一个点,当子模式稍后失败时,正则表达式引擎不允许回溯超过该点
  • (*SKIP)(*FAIL) 一起提供了一个很好的限制替代方案,你不能在上面的正则表达式中有可变长度的回顾。