[英]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? 如果是這樣,那就不要。 正則表達式是一個非常糟糕的解析器,也請參見以下問題。
在JS中,函數可以包含函數(后者又可以包含函數,依此類推):
x = function() {
this.y = function() { /* ... */ };
function z() { /* ... */ }
};
另外,您可以具有字符串文字或注釋,其中可以包含看起來像函數的(子)字符串:
var s = "function notAFunction(){}";
/*
function alsoNotAFunction(){}
*/
或包含您的正則表達式會跳閘的部分功能:
function f() {
var s = "not a closing bracket: } ";
}
因此,為回答您的問題,正則表達式將與JS中的功能匹配:它不存在。 您應該/可以為此使用適當的解析器。
今天,我面臨着同樣的挑戰,我想在字符串中查找function definations
和function 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.