代码之家  ›  专栏  ›  技术社区  ›  leeand00

在javascript源代码中匹配函数的正则表达式?

  •  3
  • leeand00  · 技术社区  · 15 年前

    是否有任何方法可以使用正则表达式匹配javascript源代码中的函数块?

    (我真的想找到与之相反的地方,但我觉得这是个不错的开始。)

    6 回复  |  直到 8 年前
        1
  •  5
  •   Joel Coehoorn    15 年前

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

    • 多线输入
    • 嵌套

    javascript功能块往往覆盖多行,您将希望找到表示块的开始和结束的匹配“”和“”大括号,这些大括号可以嵌套到未知深度。您还需要考虑注释中使用的潜在大括号。雷杰克斯会为此感到痛苦。

    但这并不意味着这是不可能的。您可能对要查找的函数的性质有其他信息。如果您可以做一些事情,比如保证注释中没有大括号,并将嵌套限制到特定的深度,那么您仍然可以构建一个表达式来实现这一点。这会有些混乱,很难维持,但至少在可能的范围内。

        2
  •  6
  •   Ja Superior    9 年前

    我有一个非常有效的javascript解决方案,这与大家的看法相反…试试这个,我用过,效果很好 function\s*([A-z0-9]+)?\s*\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)\s*\{(?:[^}{]+|\{(?:[^}{]+|\{[^}{]*\})*\})*\}

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

        3
  •  5
  •   Welbog    15 年前

    不,不是。

    函数块不是正则的,因此正则表达式不是执行该任务的正确工具。请参见,为了在JS中捕获函数块,需要计算 { 并将它们与 } ,否则你会匹配得太多或太少。正则表达式不能进行这种计数。

    只需读取您试图查看的文件并递归地管理嵌套。从概念上讲,用这种方式管理是非常容易的。

        4
  •  3
  •   Zifre    15 年前

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

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

    但是,您可以创建一个相当简单的语法来完成它(以ebnf-ish形式):

    javascript_func
    : "function" ID "(" ")" "{" body* "}"
    | "function" ID "(" params ")" "{" body* "}"
    ;
    
    params
    : ID
    | params "," ID
    
    body
    : [^{}]* // assume this is like a regex
    | "{" body* "}"
    ;
    

    哦,这也是假设你有某种lexer可以去掉空白和注释。

        5
  •  3
  •   toster-cx    9 年前

    一些regex引擎确实允许递归。比如,在php或pcre中,您可以得到这样的嵌套括号:

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

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

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

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

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

    这应该适用于基本情况。但还有一些字符串带有“”,字符串带有转义引号和其他需要担心的事情。

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

        6
  •  2
  •   Alan    8 年前

    在为我自己的项目处理了一天之后,这里有一个regex,它将分解一个JS文件以匹配所有命名函数,然后将其分解为函数名、参数和主体。

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

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