I have this regexp
var bodyRegExp = /function[\\s]+[(].+[)][\\s]+{(.+)}/;
bodyRegExp.exec("module.exports = function () { /* any content */ }");
It doesn't work. Why is it broken?
It's meant to pull the body of the function statement out of the source code.
Edit:
I'm being stupid. Trying to parse javascript with a regexp is stupid.
I have this regexp
var bodyRegExp = /function[\\s]+[(].+[)][\\s]+{(.+)}/;
bodyRegExp.exec("module.exports = function () { /* any content */ }");
It doesn't work. Why is it broken?
It's meant to pull the body of the function statement out of the source code.
Edit:
I'm being stupid. Trying to parse javascript with a regexp is stupid.
Share Improve this question edited Nov 18, 2011 at 19:28 Raynos asked Nov 18, 2011 at 19:16 RaynosRaynos 170k57 gold badges357 silver badges398 bronze badges 3- You are not making a javascript parser but trying to depile a function body... very different things? It's like saying "because you can't make a HTML parser with regex, then you can't get the href attribute of a single a element with known structure with regex". I recall some popular library doing this in their inheritance module but I can't remember the name.. I'll look it up. – Esailija Commented Nov 18, 2011 at 19:37
-
@Esailija I'm trying to parse the function body of the statement
module.exports = functionReferenceOrFunctionLiteral;
that is somewhere inside a file. That can't be done with regexp. – Raynos Commented Nov 18, 2011 at 19:40 - ok I misunderstood then. If you need the code I have it in my clipboard :P (it was from prototype.js) – Esailija Commented Nov 18, 2011 at 19:42
8 Answers
Reset to default 6Don't escape your backslashes. Do escape your curly braces. Your character set square bracket expressions are unnecessary. Use this instead:
var bodyRegExp = /function\s+\(.*\)\s+\{(.+)\}/;
Still, this is not a very robust expression - it won't work with multi-line functions and will give unexpected results when your function has more than one set of parens or curly braces - which seems extremely likely. But it should at least address the issues you are having.
Edit: If you are always dealing with a string that contains a function with no preceding or following statements, the solutions is quite simple. Just get everything after the first opening curly brace and before the last closing curly brace.
var fnBody = fn.substring(fn.indexOf("{") + 1, fn.lastIndexOf("}"));
If you are trying to extract a single function out of a string that contains more than just the one function, you'll need to write a whole parsing algorithm to do it. Or, if it is safe to do so, you could execute the JavaScript and get the function definition string by going var fn = module.exports.toString()
and then apply the above code to that string.
Function.prototype.body=function(){
this._body=this.toString().substring(this.toString().indexOf("{") + 1, this.toString().lastIndexOf("}"));
return this._body;
};
then :
myFn.body()
Just , this call,, after that you can access to body using the attribute _body
:
myFn._body
/function[\\s]+[(].+[)][\\s]+{(.+)}/
your function (/* right here is wrong */)
use are using .+ which is one or more. So you need zero or more, /function +\(.*\) +{(.+)}/
The regex you need.
This one will separately extract the arguments and the body of the function code. Returning an array of 6 items the 3rd and 5th items in the array will be the arguments and the function code body. Can be used to extract methods from objects.
You can call func.toString() then use this regex on it.
var matcharray = funcstring.match(/(function\s?)([^\.])([\w|,|\s|-|_|\$]*)(.+?\{)([^\.][\s|\S]*(?=\}))/);
Late to the party, but you could try this:
/^(?<space>\s*?)((?:async\s*?|)(?:function\s*?|))(\w+)\s*?(([\w,\s]?))\s?{(.*?^(\k<space>))}/gms
Will give you groups with function name, params, and function body.
var bodyRegExp = /\{(.+?)\}+$/;
console.log("module.exports = function () { /* any content */ }".match(bodyRegExp))
do you have to use exec??
This returns ["{ /* any content */ }", " /* any content */ "]
I'm surprised no one did the obvious regex-wise:
var fn = function whatever1() {
function whatever2() {
}
};
var body = (''+fn).match(/{([^]*)}[^}]*/)[1];
Output:
"
function whatever2() {
}
"
Perfectly suited for multiple lines; however, personally, I like @gilly3's answer the best, using indexOf
and lastIndexOf
rather than a regex for this simple case (regex may be overkill). ;)
you cannot use regular expressions to parse JavaScript language syntax because the grammar for that language is too plex for what regex can do.