2014-01-14 54 views
0

我很努力構建一個正則表達式來匹配js函數參數。我在一個項目中,我需要解析JavaScript,我需要正則表達式來匹配函數括號中的所有內容。正則表達式匹配括號中的Javascript函數

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

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

它應與「功能」或「功能富」後只匹配的東西,基本上所以它不匹配函數體內部括號之間的事情。我需要它來排除實際的'('和')'字符。此外,我'功能'或函數名稱和開幕'('之間的空白可以是無限的

這是我到目前爲止,我只接受匹配的第二個例子,只有只有一個。提前「功能」和「(」正則表達式是不是我的強項所以這可能甚至是不可能的,但由於間距

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

更新: 這是我試圖讓工作的另一種表達,它比上面的那個更接近,但只允許'function'和'('之間只有一個空格,也不包括上面的例子1

\b(?<=(function.)\()([^),]+)[^)]*\b 
+3

如果你希望使用正則表達式來解析javascript,我認爲你是在漫長的夜晚。有這個任務的語言解析器。您也可以輕鬆找到適合您需求的JavaScript語法文件。如果你希望遠遠超過這個具體問題,你應該考慮其他技術。 –

+0

爲什麼不用'function'啓動正則表達式? – elclanrs

+1

如果某些函數語法出現在字符串文字中,該怎麼辦?它應該匹配嗎?爲什麼你首先需要這個? –

回答

3

嘗試,如:

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 

更新

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

'function foo(bar){}'怎麼樣? – Sam

+1

在這種情況下,它返回酒吧,是不是需要wats? –

+0

我的不好,我誤解了你的正則表達式。 – Sam

1

Angular Sources

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

它只適用於參數(適用於您的問題),但不適用於參數。

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

首先,角度剝離可能的空間和評論。然後,在FN_ARGS中,它匹配關鍵字function後面的可選函數名稱,並提取由逗號連接的參數列表。最後,它將逗號分隔arg列表。

如果您知道該評論不會出現,您可以跳過評論部分。如果你確實想要考慮評論,那麼構建的REGEXP將會太長。

最後,不要忘記m標誌使多行模式中的正則表達式在主題字符串中的每一行的開始和結束處都符合care和dollar匹配。