2013-10-24 41 views
0

我正在使用第三方JS庫。它期望一些RegExp作爲輸入,它將用於匹配字符串的部分。現在我需要在RegExp I pass中使用lookbehind,但在JS RegExp中未實現向後看。因此,作爲解決方法,我試着從正則表達式來推導:從JS衍生出RegExp

function SubRegExp(pattern, matchIndex) { 
    this.matchIndex = matchIndex; 
    this.prototype = new RegExp(pattern); 
    this.exec = function(s) { 
     return [ this.prototype.exec(s)[this.matchIndex] ]; 
    } 
} 

我測試它像這樣:

var re = new SubRegExp('m(.*)', 1); 
console.log(re.exec("mfoo")); 
console.log("mfoo".match(re)); 

我得到的是:

["foo"] 
["o", index: 2, input: "mfoo"] 

第一輸出如預期的那樣,但我並沒有真正瞭解第二個輸出的情況。我究竟做錯了什麼?

回答

2

因此,String.prototype.match函數適用於您的自定義類實例,您應該實現toString方法,該方法返回regexp字符串。

function SubRegExp(pattern, matchIndex) { 

    this.pattern = pattern; 
    this.matchIndex = matchIndex; 
    this.rgx = new RegExp(pattern); 

    this.exec = function(s) { 
     return [ this.rgx.exec(s)[this.matchIndex] ]; 
    } 


} 

SubRegExp.prototype.toString = function(){ 
    return this.pattern; 
} 

var re = new SubRegExp('m(.*)', 1); 
console.log(re.exec('mfoo')); 
console.log('mfoo'.match(re)); 

//-> ["foo"] 
//-> ["mfoo", "foo", index: 0, input: "mfoo"] 

要解釋你的例子發生了什麼,以及爲什麼你'o'結果。實際上,它真的很有趣巧合 - 'mfoo'.match(re)re實例轉換爲字符串,然後將其用作正則表達式模式。 re.toString() === "[object Object]"

"[object Object]" - 這是在正則表達式中的一組,這就是爲什麼第一'o'匹配:)

編輯

對不起,是邁向第二輸出不是太周到。因爲使用原始正則表達式字符串(來自toString,因爲我解釋了),因此.match()不會調用您的自定義exec函數。唯一的出路是重寫match函數,但這不是一個好習慣。

(function(){ 
    var original = String.prototype.match; 
    String.prototype.match = function(mix) { 
     if (mix instanceof SubRegExp) 
      return mix.exec(this); 
     return original.call(this, mix); 
    } 
}()); 
+0

這個答案解釋了發生了什麼,但它不能解決問題。第二次調用仍然返回整個匹配字符串作爲第一次匹配,而不僅僅是第一次匹配。 – flyx