简体   繁体   中英

Regex to match args in Javascript function between parentheses

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

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);

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM