繁体   English   中英

正则表达式以匹配JavaScript函数

[英]Regular expression to match JavaScript function

是否存在与JavaScript函数匹配的正则表达式?

喜欢

function abc(var1, var2){
  ..
}

// and

abc : function(var1, var2){
  ...
},

我知道这个问题已有5年历史了,但与其他所有人所说的相反,我实际上已经按照您的要求制定了一种非常有效的做法。 尽管非常复杂,但我在自己的项目中已经使用了几次,但还没有打...……希望我早点看到这个问题。 希望这会有所帮助(如果不适合您,希望对那些正在寻找类似解决方案的人有所帮助)

function\\s*([A-z0-9]+)?\\s*\\((?:[^)(]+|\\((?:[^)(]+|\\([^)(]*\\))*\\))*\\)\\s*\\{(?:[^}{]+|\\{(?:[^}{]+|\\{[^}{]*\\})*\\})*\\}

您是否要使用正则表达式解析JS? 如果是这样,那就不要。 正则表达式是一个非常糟糕的解析器,也请参见以下问题。

什么时候应该使用解析器?

RegEx匹配XHTML自包含标签以外的打开标签

如果不应该使用正则表达式来解析HTML,那么HTML解析器将如何编写?

在JS中,函数可以包含函数(后者又可以包含函数,依此类推):

x = function() {
  this.y = function() { /* ... */ };
  function z() { /* ... */ }
};

另外,您可以具有字符串文字或注释,其中可以包含看起来像函数的(子)字符串:

var s = "function notAFunction(){}";
/* 
function alsoNotAFunction(){}
*/

或包含您的正则表达式会跳闸的部分功能:

function f() {
  var s = "not a closing bracket: } ";
}

因此,为回答您的问题,正则表达式将与JS中的功能匹配:它不存在。 您应该/可以为此使用适当的解析器。

今天,我面临着同样的挑战,我想在字符串中查找function definationsfunction usages

并使用名为esprima的解析器解决了该问题。

(注意:这是针对nodejs的,不是针对浏览器javascript的。使用npm i esprima clipboardy运行依赖npm i esprima clipboardy ,并将代码放入index.js ,并使用node index.js运行它)

var esprima = require('esprima');
const clipboardy = require('clipboardy');
var program = `
const answer = 42;
function foo(){
    alert("hi")
}
`;

//esprima.tokenize(program)
var entries = []
parsed = esprima.parseScript(program, {}, function (node, meta) {
            entries.push({
                start: meta.start.offset,
                end: meta.end.offset,
                node: node
            });
    })

clipboardy.writeSync(JSON.stringify(entries, null, 2));
console.log('full parsed data copied to clipboard!')

//find function calls
var functionCalls = entries.filter(e => e.node.type == "CallExpression")
console.log('function calls: ' + JSON.stringify(functionCalls.map (a => {return {name: a.node.callee.name, start: a.start, end: a.end}})))

//find alert function calls
var alertFunctionCalls = entries.filter(e => e.node.type == 'CallExpression' && (e.node.callee.name == 'alert'))
console.log('alert function calls: ' + JSON.stringify(alertFunctionCalls.map (a => {return {start: a.start, end: a.end}})))

//find function definations
var functionDeclarations = entries.filter(e => e.node.type == 'FunctionDeclaration')
console.log('function definations: ' + JSON.stringify(functionDeclarations.map (a => {return {name: a.node.id.name, start: a.start, end: a.end}})))

//find foo() function defination
var fooFunctionDeclaration = entries.filter(e => e.node.type == 'FunctionDeclaration' && e.node.id.name == 'foo')
console.log('foo function definations: ' + JSON.stringify(functionDeclarations.map (a => {return {start: a.start, end: a.end}})))

//remove alert function calls
var program2 = program
alertFunctionCalls.sort((a, b) => { return b.end - a.end }).forEach(n => {
    program2 = program2.substring(0, n.start) + program2.substring(n.end);
});
console.log('program after removing alert function calls: ' + program2)

我不久前写了一个正则表达式,以检测函数,因此我们可以检查是否为每个函数编写了文档,不是那么容易遵循,也不是令人惊讶的正则表达式,但是它似乎涵盖了许多不同类型的函数声明:

^(?:[\\s]+)?(?:const|let|var|)?(?:[a-z0-9.]+(?:\\.prototype)?)?(?:\\s)?(?:[a-z0-9-_]+\\s?=)?\\s?(?:[a-z0-9]+\\s+\\:\\s+)?(?:function\\s?)?(?:[a-z0-9_-]+)?\\s?\\(.*\\)\\s?(?:.+)?([=>]:)?\\{(?:(?:[^}{]+|\\{(?:[^}{]+|\\{[^}{]*\\})*\\})*\\}(?:\\s?\\(.*\\)\\s?\\)\\s?)?)?(?:\\;)?

在这里查看我测试过的类型: https//regex101.com/r/WGqfm8/9/

这不会处理所有情况,但应该抓住其中的大多数!

我故意没有添加的内容:

// won't find
const filterFn = apples.filter(() => {});
// won't find
const filterFn = apples.filter(function(){});

绝对有一些我没有涉及的内容,但是我尝试涵盖了大多数基础知识,您只需要从匹配组中删去空白

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM