给出虚拟函数:
public function handle()
{
if (isset($input['data']) {
switch($data) {
...
}
} else {
switch($data) {
...
}
}
}
我的目的是获取该函数的内容,问题是匹配花括号{...}
的嵌套模式。
我遇到了recursive patterns,但无法理解与功能正常相匹配的正则表达式。
我尝试了以下(没有递归):
$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
的。{ / p>
除了这种模式,同样的结果:
'{(\K[^}]*(?=)})/m';
答案 0 :(得分:7)
根据其他人的意见
^\s*[\w\s]+\(.*\)\s*\K({((?>"(?:[^"\\]*+|\\.)*"|'(?:[^'\\]*+|\\.)*'|//.*$|/\*[\s\S]*?\*/|#.*$|<<<\s*["']?(\w+)["']?[^;]+\3;$|[^{}<'"/#]++|[^{}]++|(?1))*)})
注意:如果您知道您的输入不包含PHP语法中的{((?>[^{}]++|(?R))*)}
或{
,那么简短的RegEx即}
即可。
[{}]
["']
[{}]
。 //...
或/*...*/
或#...
[{}]
或<<<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&#39; RegexFormatter软件完成。
随机提供Laravel的Eloquent Model.php文件(~3500行)作为输入。看看这个: 的 Live demo 强>
答案 1 :(得分:0)
这可以从内联功能块(.c)中输出头文件(.h)
查找正则表达式:
(void\s[^{};]*)\n^\{($[^}$]*)\}$
替换为:
$1;
输入:
void bar(int var)
{
foo(var);
foo2();
}
将输出:
void bar(int var);
获取具有第二个匹配模式的功能块的主体:
$2
将输出:
foo(var);
foo2();