【问题标题】:Regular Expressions for matching functions in javascript source code?javascript源代码中匹配函数的正则表达式?
【发布时间】:2009-07-08 15:23:08
【问题描述】:

有没有办法使用正则表达式匹配javascript源代码中的功能块?

(我真的想找到相反的东西,但我认为这是一个很好的起点。)

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    我有一个非常有效的 javascript 解决方案,与其他人的看法相反...试试这个,我已经使用它并且效果很好 function\s*([A-z0-9]+)?\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*\{(?:[^}{]+|\{(?:[^}{]+|\{[^}{]*\})*\})*\}

    https://regex101.com/r/zV2fO7/1

    【讨论】:

      【解决方案2】:

      有些事情是正则表达式不太擅长的。这并不意味着不可能构建一个有效的表达式,只是它可能不太合适。其中包括:

      • 多行输入
      • 嵌套

      Javascript 函数块往往会覆盖多行,并且您会想要找到匹配的“{”和“}”大括号来表示块的开始和结束,它们可以嵌套到未知的深度。您还需要考虑在 cmets 中使用的潜在大括号。 RegEx 会为此感到痛苦。

      但这并不意味着这是不可能的。您可能有关于您正在寻找的功能的性质的其他信息。如果您可以执行诸如保证 cmets 中没有大括号并将嵌套限制在特定深度之类的操作,您仍然可以构建一个表达式来执行此操作。它会有些混乱且难以维护,但至少在可能的范围内。

      【讨论】:

      • 多行输入怎么出问题?
      • 这取决于引擎 - 有些只是不支持它。其他人有错误。
      • 这不是引擎的问题而不是正则表达式吗?
      • 你可以这么说。我认为这更多是技术的问题-多线只是您需要注意的另一件事。
      【解决方案3】:

      不是真的,不。

      函数块不是正则的,因此正则表达式不是适合这项工作的工具。看,为了在 JS 中捕获功能块,您需要计算 { 的实例并将它们与 } 的实例进行平衡,否则您将匹配太多或太少。正则表达式不能做这种计数。

      只需读入您要查看的文件并递归管理嵌套即可。这种方式在概念上很容易管理。

      【讨论】:

        【解决方案4】:

        不,这是不可能的。正则表达式无法匹配嵌套的字符对。所以这样的事情会愚弄它:

        function foo() {
            if(bar) {
                baz();
            } // oops, regex would think this was end of function
        }
        

        但是,您可以创建一个相当简单的语法来执行此操作(以 EBNF 形式):

        javascript_func : "函数" ID "(" ")" "{" body* "}" | "函数" ID "(" 参数 ")" "{" body* "}" ; 参数 : ID |参数 "," ID 身体 : [^{}]* // 假设这就像一个正则表达式 | “{“ 身体* ”}” ;

        哦,这也是假设您有某种词法分析器来去除空格和 cmets。

        【讨论】:

        • 实际上,一个贪婪的正则表达式会匹配整个函数。但是,如果另一个函数跟随它,它也会被抓取。
        • 哦,你也可以有嵌套函数...(另一个函数定义)
        • @GalacticCowboy:我认为贪婪问题会相当明显,但你是对的。
        【解决方案5】:

        一些正则表达式引擎确实允许递归。在 PHP 或 PCRE 中说,你可能会得到像这样的嵌套括号:

        {(?:[^{}]+|(?R))*+}
        

        ?R 将整个表达式“粘贴”到位。要捕获函数,子组会更有用:

        function[^{]+({(?:[^{}]+|(?-1))*+})
        

        然后我们可能想要过滤掉任何打破括号的 cmets(需要 sm 标志):

        function\s+\w+\s*\([^{]+({(?:[^{}]+\/\*.*?\*\/|[^{}]+\/\/.*?$|[^{}]+|(?-1))*+})
        

        这应该适用于基本情况。但是还有带 '}' 的字符串、带转义引号的字符串和其他需要担心的事情。

        这是一个演示:https://regex101.com/r/fG4gO1/2

        【讨论】:

        • 真的很酷。我做了一些改变。 function([^{]+)({(?:[^{}]+\/\*.*?\*\/|[^{}]+\/\/.*?$|[^{}]+|(?-1))*+})
        【解决方案6】:

        在为我自己的项目折腾了一天之后,这里有一个正则表达式,它将分解一个 js 文件以匹配所有命名函数,然后将其分解为函数名称、参数和主体。

        function\s+(?<functionName>\w+)\s*\((?<functionArguments>(?:[^()]+)*)?\s*\)\s*(?<functionBody>{(?:[^{}]+|(?-1))*+})
        

        https://regex101.com/r/sXrHLI/1

        【讨论】:

        • 非常好!我尝试了一个 ES6 类,它找到了嵌入式函数(当然不是方法)。它甚至适用于缩小代码。我确实看到 cmets 中额外的打开/关闭括号是一个问题。我个人可能会选择避免对 func 进行正则表达式解析。
        猜你喜欢
        • 2017-06-27
        • 2019-05-03
        • 1970-01-01
        • 2011-05-11
        • 2018-07-14
        • 2017-08-16
        • 2011-11-29
        • 2012-09-22
        • 1970-01-01
        相关资源
        最近更新 更多