Дана фиктивная функция как таковая:
public function handle()
{
if (isset($input['data']) {
switch($data) {
...
}
} else {
switch($data) {
...
}
}
}
Мое намерение состоит в том, чтобы получить содержимое этой функции, проблема заключается в сопоставлении вложенных шаблонов фигурных скобок {...}
,
Я сталкивался рекурсивные паттерны но я не мог разобраться с регулярным выражением, которое соответствовало бы телу функции.
Я пробовал следующее (без рекурсии):
$pattern = "/function\shandle\([a-zA-Z0-9_\$\s,]+\)?". // match "function handle(...)"'[\n\s]?[\t\s]*'. // regardless of the indentation preceding the {
'{([^{}]*)}/'; // find everything within braces.
preg_match($pattern, $contents, $match);
Этот шаблон не соответствует вообще. Я уверен, что это последний бит, который не так '{([^{}]*)}/'
поскольку этот шаблон работает, когда в теле нет других фигурных скобок.
Заменив его на:
'{([^}]*)}/';
Это соответствует до закрытия }
переключателя внутри if
Заявление и остановился там (в том числе }
выключателя, но исключая тот из if
).
Как и этот шаблон, тот же результат:
'{(\K[^}]*(?=)})/m';
Согласно другим комментариям
^\s*[\w\s]+\(.*\)\s*\K({((?>"(?:[^"\\]*+|\\.)*"|'(?:[^'\\]*+|\\.)*'|//.*$|/\*[\s\S]*?\*/|#.*$|<<<\s*["']?(\w+)["']?[^;]+\3;$|[^{}<'"/#]++|[^{}]++|(?1))*)})
Примечание: короткий RegEx, т.е. {((?>[^{}]++|(?R))*)}
достаточно, если вы знаете, что ваш ввод не содержит {
или же }
вне синтаксиса PHP.
[{}]
в строке между кавычками ["']
[{}]
в блоке комментариев. //...
или же /*...*/
или же #...
[{}]
в наследство или в настоящее время <<<STR
или же <<<['"]STR['"]
В противном случае предполагается наличие пары открывающих / закрывающих скобок, а глубина вложенных скобок не важна.
Нет, если у вас нет марсианина, который живет внутри ваших кодов.
^ \s* [\w\s]+ \( .* \) \s* \K # how it matches a function definition
( # (1 start)
{ # opening brace
( # (2 start)
(?> # atomic grouping (for its non-capturing purpose only)
"(?: [^"\\]*+ | \\ . )*" # double quoted strings
| '(?: [^'\\]*+ | \\ . )*' # single quoted strings
| // .* $ # a comment block starting with //
| /\* [\s\S]*? \*/ # a multi line comment block /*...*/
| \# .* $ # a single line comment block starting with #...
| <<< \s* ["']? # heredocs and nowdocs
( \w+ ) # (3) ^
["']? [^;]+ \3 ; $ # ^
| [^{}<'"/#]++ # force engine to backtack if it encounters special characters [<'"/#] (possessive)
| [^{}]++ # default matching bahaviour (possessive)
| (?1) # recurse 1st capturing group
)* # zero to many times of atomic group
) # (2 end)
} # closing brace
) # (1 end)
Форматирование выполняется @ sln’s RegexFormatter программного обеспечения.
Красноречивый Ларавель Model.php Файл (~ 3500 строк) случайным образом задается в качестве входных данных. Проверьте это:
Живая демо
Это работает для вывода файла заголовка (.h) из встроенных функциональных блоков (.c)
Найти регулярное выражение:
(void\s[^{};]*)\n^\{($[^}$]*)\}$
Заменить:
$1;
Для ввода:
void bar(int var)
{
foo(var);
foo2();
}
будет выводить:
void bar(int var);
Получите тело функционального блока со вторым сопоставленным шаблоном:
$2
будет выводить:
foo(var);
foo2();