Я пытаюсь выполнить поиск, хотя мой код заменяет весь старый стиль PHP array()
стилем shorthand []
. Однако у меня возникают проблемы с созданием рабочего/надежного регулярного выражения...
В настоящее время у меня есть: (^|[\s])array\((['"](\s\S)['"]|[^)])*\)
(View on 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 для этого...
EDIT: Это не ответ на вопрос, но одна из альтернатив заключается в использовании проверенной проверки подлинности Traditional syntax array literal detected
PHPStorm....
Как:
Code
Run inspection by name...
(Ctrl + Alt + Shift + I)Traditional syntax array literal detected
<Enter>
<Enter>
Inspection
.Это возможно, но не тривиально, поскольку вам нужно полностью описать две части синтаксиса 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)...)
и содержит именованные определения подшаблонов для разных полезных элементов (в частности, "строка" "com" и "nestedpar"). Эти подшаблоны будут использоваться позже в основном шаблоне.
Идея состоит в том, чтобы никогда не искать parenthese внутри комментария, строки или из вложенных круглых скобок.
Первая строка: (?:\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
while используется для обработки объявлений вложенных массивов, поскольку невозможно выполнить замену нескольких уровней вложенности за один проход (однако есть путь с preg_replace_callback
но это не очень удобно). Чтобы остановить цикл, используется последний параметр preg_replace
. Этот параметр содержит количество замен, выполняемых в целевой строке.