使用正则表达式查找/替换array()

时间:2014-11-07 14:09:05

标签: php arrays regex

我尝试搜索我的代码,用速记array()样式替换所有旧式PHP []。但是,我在创建一个可靠/可靠的正则表达式时遇到了一些麻烦...

我目前拥有的内容:(^|[\s])array\((['"](\s\S)['"]|[^)])*\)(在Regex101上查看)

// Match All
array('array()')

array('key' => 'value');
array(
    'key'  => 'value',
    'key2' => '(value2)'
);
    array()
  array()
array()

// Match Specific Parts
function (array $var = array()) {}
$this->in_array(array('something', 'something'));

// Don't match
toArray()
array_merge()
in_array();

我为它创建了Regex101 ...

编辑:这不是问题的答案,但另一种方法是使用PHPStorm Traditional syntax array literal detected检查......

如何:

  • 打开Code菜单
  • 点击Run inspection by name...(Ctrl + Alt + Shift + I)
  • 输入Traditional syntax array literal detected
  • <Enter>
  • 指定您希望在
  • 上运行它的范围
  • <Enter>
  • Inspection窗口中查看/应用更改。

1 个答案:

答案 0 :(得分:4)

这是可能的,但不是微不足道的,因为您需要完整地描述PHP语法的两个部分(即字符串和注释),以防止在其中解释括号。以下是使用PHP本身的方法:

$pattern = <<<'EOD'
~
(?(DEFINE)
    (?<quotes> (["']) (?: [^"'\\]+ | \\. | (?!\g{-1})["'] )*+ (?:\g{-1}|\z) )
    (?<heredoc> <<< (["']?) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*) \g{-2}\R
                (?>\N*\R)*?
                (?:\g{-1} ;? (?:\R | \z) | \N*\z)
    )
    (?<string> \g<quotes> | \g<heredoc> )

    (?<inlinecom> (?:// |\# ) \N* $ )
    (?<multicom> /\*+ (?:[^*]+|\*+(?!/))*+ (?:\*/|\z))
    (?<com> \g<multicom> | \g<inlinecom> )

    (?<nestedpar> \( (?: [^()"'<]+ | \g<com> | \g<string> | < | \g<nestedpar>)*+ \) )
)

(?:\g<com> | \g<string> ) (*SKIP)(*FAIL)
|
(?<![-$])\barray\s*\( ((?:[^"'()/\#]+|\g<com>|/|\g<string>|\g<nestedpar>)*+) \)
~xsm
EOD;

do {
    $code = preg_replace($pattern, '[${11}]', $code, -1, $count);
} while ($count);

模式包含两部分,第一部分是定义部分,第二部分是主模式。

定义部分包含在(?(DEFINE)...)之间,并包含不同有用元素的命名子模式定义(特别是&#34;字符串&#34;&#34; com&#34;和&#34; nestedpar&#34 )。这些子模式稍后将在主模式中使用。

我们的想法是永远不要在注释,字符串或嵌套括号中搜索括号。

第一行:(?:\g<com> | \g<string> ) (*SKIP)(*FAIL)将跳过所有注释和字符串,直到下一个数组声明(或直到字符串结尾)。

最后一行描述了数组声明本身,详情:

(?<![-$])\b        # check if "array" is not a part of a variable or function name
array \s*\(
(                   # capture group 11
    (?:             # describe the possible content
        [^"'()/\#]+ # all that is not a quote, a round bracket, a slash, a sharp
      |             # OR
        \g<com>     # a comment
      |
        /           # a slash that is not a part of a comment
      |
        \g<string>  # a string
      |
        \g<nestedpar> # nested round brackets
    )*+
)
\)

pattern demo

code demo

关于嵌套数组声明:

当找到嵌套数组声明块时,当前模式只能找到最外层的数组声明。

do...while循环用于处理嵌套数组声明,因为无法在一次传递中执行多个嵌套级别的替换(但是,preg_replace_callback有一种方法,但它不是很方便)。要停止循环,使用preg_replace的最后一个参数。此参数包含目标字符串中执行的替换次数。