【问题标题】:Regex to check for new line正则表达式检查新行
【发布时间】:2012-08-20 03:47:45
【问题描述】:

我想检查 if 语句是在一行还是在下一行没有大括号:

if (blah === blah)
    do something

或:

if (foo === foo) do something

我目前的正则表达式是

/\)(?!.*\{)/

但不起作用。有人有什么想法吗?

详细说明此正则表达式不会提取的唯一 If 语句如下:

if (foo === bar)
{

【问题讨论】:

标签: php regex


【解决方案1】:

简单的\r\n(回车换行)

/[\r\n]/

【讨论】:

  • 为什么需要不区分大小写?
【解决方案2】:

新行可能是\n (UNIX)、\r\n (Windows)、\r(为了更好的衡量标准)。广泛匹配新行的表达式是:

/\r\n|\r|\n/

要检查一个表达式是否在一行,你可以这样做:

if( preg_match( '/\r\n|\r|\n/', $string ) ) {
    // on more than one line
    ...
} else {
   // on one line
   ...
}

要进一步开发此功能以应用于您的 if ... do 语句的特定示例,您可以这样做:

if( preg_match( '/if *\([^\)]+\) *(\r\n|\r|\n) *do /', $string ) ) {
    // on more than one line
    ...
} elseif( preg_match( '/if *\([^\)]+\) *do /', $string ) ) {
   // on one line
   ...
}

【讨论】:

  • 您可以了解一些关于 atomic grouping 的知识,以进一步了解您建议的模式可能存在问题的部分。
  • @hakra,如果我的逻辑有误,也许你可以准确地说明它是什么。我输入的应该可以工作。
  • 您使用的字符和序列——全部单独使用——都很好。问题是当你有这些的组合时。因此,原子分组,它会注意回溯不会咬你。对于单个换行符,这可能不是什么大问题,但如果有多个行,它开始变得更加成问题。
  • 如果我试图匹配整个字符串,那可能是真的。但由于我的逻辑只查找任何单个换行片段(在许多潜在片段中),因此您的担忧并不适用。
  • 是的,PCRE 将消耗第一个匹配的子组模式替代方案,并且您选择了最大的第一个。然而,回溯仍然适用于 IIRC,虽然它不是必需的 - 所以即使对于单场比赛,它也可能有一些缺点。请注意,我没有写你的模式是错误的。
【解决方案3】:

如果您想专门检查 if,请使用:

(if[ ()\w=]+)\r\n

如果if 有换行符,则返回true,否则返回false

【讨论】:

    【解决方案4】:

    您也需要使 . 匹配换行符:

    /\)(?!.*\{)/s
                ^
        PCRE_DOTALL Modifier
    

    这是通过the s (PCRE_DOTALL ) modifier 完成的(如 cmets 中所写):

    s (PCRE_DOTALL)

    如果设置了此修饰符,则模式中的点元字符匹配所有字符,包括换行符。没有它,换行符被排除在外。这个修饰符等价于 Perl 的 /s 修饰符。诸如 [^a] 之类的否定类始终匹配换行符,与此修饰符的设置无关。

    【讨论】:

      【解决方案5】:

      您正在寻找不使用大括号的 if 语句,但您的模式需要大括号。

      这是我的建议:(Demo)

      $strings = [
      'if (blah === blah)
          do something',
      'if (foo === foo) do something',
      'if (bah === bah) {
          do something
      }',
      'if (bar === bar) {do something}'
      ];
      
      foreach ($strings as $string) {
          var_export(preg_match('~if\s*\(.*?\)\s*(\{)?~', $string, $m) ? $m : '');
          echo "\nHas curly brace: " , isset($m[1]) ? 'Yes' : 'No';
          echo "\n---\n";
      }
      

      输出:

      array (
        0 => 'if (blah === blah)
          ',
      )
      Has curly brace: No
      ---
      array (
        0 => 'if (foo === foo) ',
      )
      Has curly brace: No
      ---
      array (
        0 => 'if (bah === bah) {',
        1 => '{',
      )
      Has curly brace: Yes
      ---
      array (
        0 => 'if (bar === bar) {',
        1 => '{',
      )
      Has curly brace: Yes
      ---
      

      基本上,使用\s* 表示标记中可能出现没有空格/换行符、空格/换行符、多个空格/换行符的位置。

      我的模式不会捕获带有多行表达式的if 语句。要适应这些边缘情况,请添加 s 模式修饰符以允许 . 匹配换行符。

      【讨论】:

        猜你喜欢
        • 2010-12-16
        • 2015-03-12
        • 2011-12-19
        • 1970-01-01
        • 2022-06-16
        • 1970-01-01
        • 1970-01-01
        • 2012-12-12
        • 2013-04-01
        相关资源
        最近更新 更多