簡體   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