REGEX到最后一组括号PHP

时间:2014-02-07 13:31:06

标签: php regex

我有以下正则表达式:

    (require|include)(_once)?(?|\(([^)]+)\)| ([^\s;]+))

它会发现以下内容没有问题:

    require(foo);
    require_once(foo);
    require foo;
    require_once foo;
    include(foo);
    include_once(foo);
    include foo;
    include_once foo;

但我遇到的问题是一些代码如下:

    require(foo() . bar());

因此,当代码运行时,它正在执行:

    require(somefunction(foo()) . bar());

在第一个结束新功能而不是在);

好吧让它使用:

    (require|include)(_once)?(?|[^\(]*\((.*)\)[\);$+]*| ([^\s;]+))

然而,如果有评论,它会起作用,如果该行看起来像:

    include(foo); // Some comment include()

当跑步结束时:

    include(somefunction(foo);
由于评论,

缺少其中一个右括号。请注意我无法删除评论

需要加入;照顾这个最后的结果是:

    (require|include)(_once)?(?|[^\(]*\((.*)\);[\);$+]*| ([^\s;]+))

2 个答案:

答案 0 :(得分:0)

根据您的模式的想法,您可以将其更改为:

(require|include)(_once)?(?|(\(((?>[^()]++|(?-2))*)\))#\(([^)]+)\)|( )([^\s;]+))

请注意,括号内容现在位于下一个捕获组中。

答案 1 :(得分:0)

我认为您的输入字符串符合两种可能情况中的一种:requireinsert 有括号的那些,以及没有括号的那些

示范

<?php

$strings = array(
  'require(foo);',
  'require_once(foo);',
  'require foo;',
  'require_once foo;',
  'include(foo);',
  'include_once(foo);',
  'include foo;',
  'include_once foo;',
  'require(foo() . bar());');

foreach($strings as $string) {
  $with_paren = '((require|include)(_once)?\()(.*)\);';
  $without_paren = '((require|include)(_once)? )(.*);';
  preg_match("/$with_paren|$without_paren/", $string, $matches);
  if (array_key_exists(1, $matches) && strlen($matches[1])) {
    print $string . " => " . $matches[1] . "somefunction(" . $matches[4] . "));\n";
  }
  else if (array_key_exists(5, $matches) && strlen($matches[5])) {
    print $string . " => " . $matches[5] . "somefunction(" . $matches[8] . ");\n";
  }
  else {
    print $string . " DID NOT MATCH\n";
  }

  // Uncomment below to see original string followed by array of match elements
  // print $string . "\n";
  // print_r($matches);
}

结果输出

require(foo); => require(somefunction(foo));
require_once(foo); => require_once(somefunction(foo));
require foo; => require somefunction(foo);
require_once foo; => require_once somefunction(foo);
include(foo); => include(somefunction(foo));
include_once(foo); => include_once(somefunction(foo));
include foo; => include somefunction(foo);
include_once foo; => include_once somefunction(foo);
require(foo() . bar()); => require(somefunction(foo() . bar()));

解释

您会注意到代码的关键行如下:

  $with_paren = '((require|include)(_once)?\()(.*)\);';
  $without_paren = '((require|include)(_once)? )(.*);';
  preg_match("/$with_paren|$without_paren/", $string, $matches);

我刚将其分为$with_paren$without_paren字符串,但整个正则表达式可以写成一行:

  ((require|include)(_once)?\()(.*)\);|((require|include)(_once)? )(.*);

我的代码示例使用PHP的preg_match函数,该函数搜索与正则表达式的匹配,然后将匹配的元素放入数组中,我将其命名为$matches。有关preg_match的更多信息可以是found here

如果您的输入字符串是有括号的情况,那么您将在$matches[1]处有一个字符串(因为这是第一个匹配的子表达式)。如果您的输入字符串是没有括号的情况,那么您将在$matches[5]处有一个字符串(因为那是匹配的第五个子表达式)。

我提供的PHP代码检查发生了哪种类型的匹配,然后输出原始字符串的重写,但现在插入了somefunction(...)。当然,这只是为了演示目的,以便您可以看到它的工作原理。希望正则表达式对你有所帮助。