我正在使用第三方JS库。它期望一些RegExp作为输入,它将用于匹配字符串的部分。现在我需要在RegExp I传递中使用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"]
第一个输出是预期的,但我真的不知道第二个输出发生了什么。我做错了什么?
答案 0 :(得分: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'
匹配的原因:)
修改强>
抱歉,对第二次输出并不太注意。 .match()
不会调用您的自定义exec
函数,因为使用了原始正则表达式字符串(来自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);
}
}());