Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular Expression to get parameter list from function definition [duplicate]

Possible Duplicate:
How to get function parameter names/values dynamically from javascript

I'm currently working on a project in javascript (node.js) that has me trying to get an array of parameter names (NOT values, I do not need arguments) from a function. I'm currently using Function.toString() to get the function string and then running a regex against that to get my parameter list.

Let's take the following SIMPLE example:

var myFunction = function (paramOne, paramTwo) { ... }

Running my regex against this, and then doing some string magic (split, etc) I would expect an array back like this:

paramList = ['paramOne', 'paramTwo']

I have something that works but I'm feeling like it's probably not the best solution given some of the funky characters javascript lets you use for variable names and that javascript will let you define functions on multiple lines.

Here is what I currently have:

function.*[\w\s$]*(\((.*[\w\s,$]*)\))

This gives me my "match" in group 1 and then my param list without parens in group 2, which is cool. Is this really the best way to do what I want? Is there a better regular expression I could use for this? I'm not really looking for something "simpler" but really just something that could catch all possible situations.

Any help would be appreciated, and many thanks in advance!

like image 771
Jason L. Avatar asked Dec 19 '12 12:12

Jason L.


People also ask

How do I get a list of function arguments in python?

To extract the number and names of the arguments from a function or function[something] to return ("arg1", "arg2"), we use the inspect module. The given code is written as follows using inspect module to find the parameters inside the functions aMethod and foo.

What is ?: In regex?

'a' (which in this case ?: is doing it is matching with a string but it is excluding whatever comes after it means it will match the string but not whitespace(taking into account match(numbers or strings) not additional things with them.)

How can you get the type of arguments passed to a function?

There are two ways to pass arguments to a function: by reference or by value. Modifying an argument that's passed by reference is reflected globally, but modifying an argument that's passed by value is reflected only inside the function.

Which of the following function returns an array of all parameters provided to function?

func_get_args( ) returns an array of all parameters provided to the function, func_num_args( ) returns the number of parameters provided to the function, and func_get_arg( ) returns a specific argument from the parameters.


1 Answers

Preface: By far, the best way to handle this is to use a JavaScript parser rather than trying to do it with a single regular expression. Regular expressions can be part of a parser, but no one regular expression can do the work of a parser. JavaScript's syntax (like that of most programming languages) is far too complex and context-sensitive to be handled with a simple regular expression or two. There are several open source JavaScript parsers written in JavaScript. I strongly recommend using one of those, not what's below.


The easiest thing would be to capture everything in the first set of parens, and then use split(/\s*,\s*/) to get the array.

E.g.:

var str = "function(   one  ,\ntwo,three   ,   four   ) { laksjdfl akjsdflkasjdfl }";
var args = /\(\s*([^)]+?)\s*\)/.exec(str);
if (args[1]) {
  args = args[1].split(/\s*,\s*/);
}
console.log("args: ", args);

How the above works:

  1. We use /\( *([^)]+?) *\)/ to match the first opening parenthesis (\( since ( is special in regexes), followed by any amount of optional whitespace, followed by a capture group capturing everything but a closing parenthesis (but non-greedy), followed by any amount of optional whitespace, followed by the closing ).

  2. If we succeed, we split using /\s*,\s*/, which means we split on sequences which are zero or more whitespace characters (\s*) followed by a comma followed by zero or more whitespace characters (this whitespace thing is why the args in my example function are so weird).

As you can see from the example, this handles leading whitespace (after the ( and before the first argument), whitespace around the commas, and trailing whitespace — including line breaks. It does not try to handle comments within the argument list, which would markedly complicate things.

Note: The above doesn't handle ES2015's default parameter values, which can be any arbitrary expression, including an expression containing a ) — which breaks the regex above by stopping its search early:

var str = "function(   one  ,\ntwo = getDefaultForTwo(),three   ,   four   ) { laksjdfl akjsdflkasjdfl }";
var args = /\(\s*([^)]+?)\s*\)/.exec(str);
if (args[1]) {
  args = args[1].split(/\s*,\s*/);
}
console.log("args: ", args);

Which brings us full circle to: Use a JavaScript parser. :-)

like image 56
T.J. Crowder Avatar answered Sep 20 '22 21:09

T.J. Crowder