2011-11-18 38 views
1

I have this regexp正則表達式來提取函數體

var bodyRegExp = /function[\\s]+[(].+[)][\\s]+{(.+)}/; 

bodyRegExp.exec("module.exports = function() { /* any content */ }"); 

它不工作。爲什麼它壞了?

這意味着將函數聲明的主體從源代碼中提取出來。

編輯:

我太傻了。試圖用正則表達式解析javascript是愚蠢的。

+0

你不是在做一個JavaScript解析器,但試圖反編譯一個函數體...非常不同的東西?這就像說「因爲你不能用正則表達式創建一個HTML解析器,那麼你不能用正則表達式獲得具有已知結構的單個元素的href屬性」。我記得一些流行的庫在他們的繼承模塊中這樣做,但我不記得名字了。我會查找它。 – Esailija

+0

@Esailija我想解析語句'module.exports = functionReferenceOrFunctionLiteral;'這是文件內的某個地方的函數體。這不能用正則表達式來完成。 – Raynos

+0

好吧我誤解了。如果你需要我的剪貼板中的代碼:P(它來自prototype.js) – Esailija

回答

-4

您不能使用正則表達式來解析JavaScript語言語法,因爲該語言的語法對於正則表達式可以執行的操作來說太複雜。

+3

Pfft。我有一個Visual Studio宏,它使用正則表達式來解析JavaScript文件並在所有代碼塊周圍添加可摺疊區域。它的作品非常漂亮。 – gilly3

+8

和我有一卷膠帶,可以很好地解決我的汽車問題。 –

+0

我可能會同意,「你不應該使用正則表達式」,但不能與「你*不能*使用正則表達式」。請爲他提供一個替代的,非正則表達式來訪問函數體。 (或者我自動化在Visual Studio中的JavaScript文件中創建可摺疊區域) – gilly3

0
var bodyRegExp = /\{(.+?)\}+$/; 

console.log("module.exports = function() { /* any content */ }".match(bodyRegExp)) 

你必須使用exec?

這將返回["{ /* any content */ }", " /* any content */ "]

+0

'.exec'是'.match' – Raynos

+0

的優秀版本,很酷,不知道。 – rlemon

+0

'bodyRegExp'對於OP的回答是可以的,但是如果有多行的話就不好。 –

1
/function[\\s]+[(].+[)][\\s]+{(.+)}/ 

function (/* right here is wrong */)

使用使用。+這是一個以上。所以你需要零或更多,/function +\(.*\) +{(.+)}/

4

不要逃避你的反斜槓。避開你的大括號。您的字符集方括號表達式是不必要的。使用這個來代替:

var bodyRegExp = /function\s+\(.*\)\s+\{(.+)\}/; 

不過,這並不是一個非常強大的表達 - 它不會多線功能的工作,會給意外的結果,當你的函數有一組以上的括號或大括號的 - 這似乎極有可能。但它至少應該解決您遇到的問題。

編輯:如果你總是處理一個字符串,其中包含一個函數沒有前面或後面的語句,解決方案是非常簡單的。只需在第一個開口大括號之後和最後一個關閉大括號之前獲得所有內容。

var fnBody = fn.substring(fn.indexOf("{") + 1, fn.lastIndexOf("}")); 

如果您嘗試提取一個單一的功能了,它包含的不僅僅是一個功能更字符串,你需要寫一個整體分析算法來做到這一點。或者,如果安全的話,您可以執行JavaScript並通過var fn = module.exports.toString()獲取函數定義字符串,然後將上面的代碼應用於該字符串。

1

你需要的正則表達式。

這一個將單獨提取參數和函數代碼的主體。返回6個項目的數組,數組中的第3個和第5個項目將是參數和函數代碼體。可以用來從對象中提取方法。

你可以調用func.toString()然後使用它的正則表達式。

var matcharray = funcstring.match(/(function\s?)([^\.])([\w|,|\s|-|_|\$]*)(.+?\{)([^\.][\s|\S]*(?=\}))/); 
2
Function.prototype.body=function(){ 

    this._body=this.toString().substring(this.toString().indexOf("{") + 1, this.toString().lastIndexOf("}")); 
    return this._body; 
}; 

則:

myFn.body() 

只是,這種通話,,後,您可以使用屬性_body進入人體:

myFn._body 
+0

多數民衆贊成在一個不錯的hackish方式 –

0

我很驚訝沒有一個做了明顯的正則表達式:

var fn = function whatever1() { 
    function whatever2() { 
    } 
}; 
var body = (''+fn).match(/{([^]*)}[^}]*/)[1]; 

輸出:

" 
    function whatever2() { 
    } 
" 

完全適合多行;然而,就我個人而言,我喜歡@ gilly3的回答最好,使用indexOflastIndexOf而不是這個簡單的例子的正則表達式(正則表達式可能是矯枉過正)。 ;)