0

I am struggling with building a regular expression to match js function parameters. I working on a project where I need to parse javascript and I need regex that will match everything between parentheses for functions.

function foo (bar) {}  // should match 'bar'

Foo.bar = function  (baz, obj) {} // should match only 'baz, obj'

It should only match stuff with after 'function' or 'function foo', basically so it doesn't match things between paren inside of function bodies. I need it to exclude the actual '(' and ')' chars. Also I the whitespace between 'function' or the function name and the opening '(' can be infinite.

Here is what I have so far and I am only getting matches for the second example and only if there is just one space between the 'function' and '('. Regex isn't my strong suit so this may not even be possible but Thanks in advance!

(?<=,|\()([#a-z0-9]+)(?=(,?[#a-z0-9]+)+\)|\))

Update: This is another expression I have trying to get working. It is closer than the one above but only allows exactly one space between 'function' and '('. also it doesn't cover case 1 above.

\b(?<=(function.)\()([^),]+)[^)]*\b
5
  • 3
    I think you're in for a long night if you're hoping to use regex to parse javascript. There are language parsers for this task. You can also probably easily find a javascript grammar file suitable for your needs. If you're hoping to go much further than this specific question, you should consider other techniques. Commented Jan 14, 2014 at 3:53
  • Why don't you start the regex with function? Commented Jan 14, 2014 at 3:55
  • 1
    What if some function syntax appears in a string literal? Should it match it? Why do you need this in the first place? Commented Jan 14, 2014 at 3:57
  • Honestly most of this regex has been found from searching the web. Just doesn't fully cover my needs. this is for a syntax highlighter so regex is really the best bet. Commented Jan 14, 2014 at 4:09
  • You don't indicate what your host language/environment is, but if it's for prettifying, why not try google prettify? google-code-prettify.googlecode.com/svn/trunk/README.html Commented Jan 14, 2014 at 4:11

2 Answers 2

5

try like:

var s = "Foo.bar = function  (baz, obj) {}"
var s2 = s.match(/function[^(]*\(([^)]*)\)/)[1];
console.log(s2); //would give baz and obj


var s = "function foo (bar) {}";
var s2 = s.match(/function[^(]*\(([^)]*)\)/)[1];
console.log(s2); //returns bar

update:

var pattern = /\(([^)]+)/;
var s = "Foo.bar = function  (baz, obj) {}"
var s2 = s.match(pattern)[1];
console.log(s2);
Sign up to request clarification or add additional context in comments.

6 Comments

What about function foo (bar) {}?
in that case it returns bar, isnt that wats required..?
What is the pattern variable for?
sorry, had added that for testing in my console, removed that
this seems to be matching 'function (bar, obj)' and 'function foo (bar)'. I am testing it on Regexr. I need just whats in those paren.
|
1

From Angular Sources

TL;DR: var FN_ARG = /^function\s*[^\(]*\(\s*([^\)]*)\)/m, then str.match(FN_ARG)[1]

It only works on parameter(which shall be appropriate for your question), but not argument.

var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var $injectorMinErr = minErr('$injector');
function annotate(fn) {
  var $inject,
      fnText,
      argDecl,
      last;

  if (typeof fn == 'function') {
    if (!($inject = fn.$inject)) {
      $inject = [];
      if (fn.length) {
        fnText = fn.toString().replace(STRIP_COMMENTS, '');
        argDecl = fnText.match(FN_ARGS);
        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
            arg.replace(FN_ARG, function(all, underscore, name){
              $inject.push(name);
              });
            });
      }
      fn.$inject = $inject;
    }
  } else if (isArray(fn)) {
    last = fn.length - 1;
    assertArgFn(fn[last], 'fn');
    $inject = fn.slice(0, last);
  } else {
    assertArgFn(fn, 'fn', true);
  }
  return $inject;
}

First, angular strips off possible spaces and comments. Then, in FN_ARGS, it matches optional function name after the keyword function, and extract argument list concatenated by comma.And finally it splits the arg list by commas.

You can probably skip comment part, if you know that comment will not appear. If you do want to take comment into considerations, the constructed REGEXP will be too long.

Lastly, don't forget the m flag to make the regex in multiple line mode that caret and dollar match at the start and end of each line in the subject string.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.