最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

regex - Regular expression to match JavaScript function - Stack Overflow

programmeradmin7浏览0评论

Is there a regular expression that matches JavaScript functions?

Like

function abc(var1, var2){
  ..
}

// and

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

Is there a regular expression that matches JavaScript functions?

Like

function abc(var1, var2){
  ..
}

// and

abc : function(var1, var2){
  ...
},
Share Improve this question edited Aug 6, 2019 at 18:16 Wyck 11.8k8 gold badges47 silver badges78 bronze badges asked Nov 17, 2010 at 12:03 plezplez 8,33213 gold badges51 silver badges56 bronze badges 1
  • 2 You think you do. But you don't. What are you trying to actually acplish? – annakata Commented Nov 17, 2010 at 13:31
Add a ment  | 

5 Answers 5

Reset to default 13

I know this question is 5 years old, but contrary to what everyone else has said, i have actually concocted a quite effective pattern for doing as you have asked. Albeit, quite plex, I have used this several times in my own projects and I've yet to have a hiccup... wish I had seen this question much sooner. Hope this helps (If not for you, hopefully for those who are searching for a similar solution)

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

In JS, a function can contain functions (which in turn can contain functions, and so on):

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

Also, you can have string literals or ments that can contain (sub) strings that either look like functions:

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

or contain parts of functions your regex would trip over:

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

So, to answer you question what the regex would be to match functions in JS: it does not exist. You should/could use a proper parser for this.

Are you trying to parse JS with regex? If so, DON'T. Regex is a VERY BAD parser see these questions as well.

When should I use a parser?

RegEx match open tags except XHTML self-contained tags

If you're not supposed to use Regular Expressions to parse HTML, then how are HTML parsers written?

I wrote a regular expression a while back, to detect functions, so we can check if there is documentation written for every function, not that easy to follow, not an amazing regular expression, but it seems to cover a lot of different types of function declarations:

^(?:[\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?)?)?(?:\;)?

See the types I've tested here: https://regex101./r/WGqfm8/9/

This wont handle every case, but should grab most of them!

Things I purposely didn't add:

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

There's most definitely something I'm not covering, but I tried to cover most of the basics, you'll just need to trim whitespace from the match groups

Today i faced same challenge, i wanted to find function definations and function usages in a string.

And solved it by using a parser called esprima.

(Note: this is for nodejs , not browser javascript. run dependencies with npm i esprima clipboardy and put the code in index.js and run it with 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)

发布评论

评论列表(0)

  1. 暂无评论