【问题标题】:Regex for a multiline string with PHP preg_match带有 PHP preg_match 的多行字符串的正则表达式
【发布时间】:2015-08-27 18:03:30
【问题描述】:

我正在尝试为多行字符串构建一个模式,它必须以 <?phpwhitespace + <?php 开头,并且 NOT?>?> + 结尾whitespace.

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

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

【问题讨论】:

  • 如果你只是先trim() 字符串,这会容易得多,可以通过简单的str_pos 调用来完成
  • 在我的情况下不可能。在这里,我只是准备模式以将它们传递给另一个脚本。

标签: php regex preg-match


【解决方案1】:

你可以使用

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

demo

正则表达式解释:

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

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

占有量词是一种防止正则表达式引擎 尝试所有排列。这主要对性能有用 原因。

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

【讨论】:

  • 我认为 OP 希望 不以 ?&gt;?&gt;whitespace* 结尾
  • 是的,虽然我不喜欢双重否定后视,但它确实有效。但老实说,我并没有否决其他人的回答。
  • @anubhava:现在应该
  • 是的,现在可以了,而且比 2 lookbehinds +1 好得多
【解决方案2】:

在 PHP 中,你可以使用这个正则表达式:

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

RegEx Demo

  • ^\s*&lt;\?php 在行首匹配可选的空格和文字 &lt;?php
  • (?:.(?!\?&gt;\s*$))* 将匹配任何 0 个或多个不以 ?&gt;whitespace* 结尾的字符,使用否定前瞻。

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

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

RegEx Demo 2

  • (*FAIL) 的行为类似于失败的否定断言,是 (?!) 的同义词
  • (*SKIP) 定义了一个点,当子模式稍后失败时,正则表达式引擎不允许回溯。
  • (*SKIP)(*FAIL) 一起提供了一个很好的限制替代方案,您不能在上面的正则表达式中进行可变长度的后视。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    相关资源
    最近更新 更多