我尝试搜索我的代码,用速记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
窗口中查看/应用更改。答案 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
)*+
)
\)
关于嵌套数组声明:
当找到嵌套数组声明块时,当前模式只能找到最外层的数组声明。
do...while
循环用于处理嵌套数组声明,因为无法在一次传递中执行多个嵌套级别的替换(但是,preg_replace_callback
有一种方法,但它不是很方便)。要停止循环,使用preg_replace
的最后一个参数。此参数包含目标字符串中执行的替换次数。