【发布时间】:2009-07-08 15:23:08
【问题描述】:
有没有办法使用正则表达式匹配javascript源代码中的功能块?
(我真的想找到相反的东西,但我认为这是一个很好的起点。)
【问题讨论】:
标签: javascript regex
有没有办法使用正则表达式匹配javascript源代码中的功能块?
(我真的想找到相反的东西,但我认为这是一个很好的起点。)
【问题讨论】:
标签: javascript regex
我有一个非常有效的 javascript 解决方案,与其他人的看法相反...试试这个,我已经使用它并且效果很好
function\s*([A-z0-9]+)?\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*\{(?:[^}{]+|\{(?:[^}{]+|\{[^}{]*\})*\})*\}
【讨论】:
有些事情是正则表达式不太擅长的。这并不意味着不可能构建一个有效的表达式,只是它可能不太合适。其中包括:
Javascript 函数块往往会覆盖多行,并且您会想要找到匹配的“{”和“}”大括号来表示块的开始和结束,它们可以嵌套到未知的深度。您还需要考虑在 cmets 中使用的潜在大括号。 RegEx 会为此感到痛苦。
但这并不意味着这是不可能的。您可能有关于您正在寻找的功能的性质的其他信息。如果您可以执行诸如保证 cmets 中没有大括号并将嵌套限制在特定深度之类的操作,您仍然可以构建一个表达式来执行此操作。它会有些混乱且难以维护,但至少在可能的范围内。
【讨论】:
不是真的,不。
函数块不是正则的,因此正则表达式不是适合这项工作的工具。看,为了在 JS 中捕获功能块,您需要计算 { 的实例并将它们与 } 的实例进行平衡,否则您将匹配太多或太少。正则表达式不能做这种计数。
只需读入您要查看的文件并递归管理嵌套即可。这种方式在概念上很容易管理。
【讨论】:
不,这是不可能的。正则表达式无法匹配嵌套的字符对。所以这样的事情会愚弄它:
function foo() {
if(bar) {
baz();
} // oops, regex would think this was end of function
}
但是,您可以创建一个相当简单的语法来执行此操作(以 EBNF 形式):
javascript_func : "函数" ID "(" ")" "{" body* "}" | "函数" ID "(" 参数 ")" "{" body* "}" ; 参数 : ID |参数 "," ID 身体 : [^{}]* // 假设这就像一个正则表达式 | “{“ 身体* ”}” ;哦,这也是假设您有某种词法分析器来去除空格和 cmets。
【讨论】:
一些正则表达式引擎确实允许递归。在 PHP 或 PCRE 中说,你可能会得到像这样的嵌套括号:
{(?:[^{}]+|(?R))*+}
?R 将整个表达式“粘贴”到位。要捕获函数,子组会更有用:
function[^{]+({(?:[^{}]+|(?-1))*+})
然后我们可能想要过滤掉任何打破括号的 cmets(需要 sm 标志):
function\s+\w+\s*\([^{]+({(?:[^{}]+\/\*.*?\*\/|[^{}]+\/\/.*?$|[^{}]+|(?-1))*+})
这应该适用于基本情况。但是还有带 '}' 的字符串、带转义引号的字符串和其他需要担心的事情。
【讨论】:
function([^{]+)({(?:[^{}]+\/\*.*?\*\/|[^{}]+\/\/.*?$|[^{}]+|(?-1))*+})
在为我自己的项目折腾了一天之后,这里有一个正则表达式,它将分解一个 js 文件以匹配所有命名函数,然后将其分解为函数名称、参数和主体。
function\s+(?<functionName>\w+)\s*\((?<functionArguments>(?:[^()]+)*)?\s*\)\s*(?<functionBody>{(?:[^{}]+|(?-1))*+})
【讨论】: