我正在使用第三方JS库。它期望某些RegExp作为输入,将用于匹配字符串的各个部分。现在,我需要在我通过的RegExp中使用一个lookbehind,但是JS RegExp中没有实现lookbehind。因此,作为解决方法,我尝试从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"]


第一个输出与预期的一样,但是我真的不了解第二个输出的情况。我究竟做错了什么?

最佳答案

为了使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'被匹配的原因:)

编辑

抱歉,对第二种输出不太关注。 .match()不会调用您的自定义exec函数,因为使用了原始的regexp字符串(如我所解释,来自toString的字符串)。唯一的方法是重写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);
    }
}());

关于javascript - 从JS RegExp派生,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19573239/

10-15 10:04