这是一个难题,我知道如何解决它,但我想知道是否有一个(更简单)方法。
简而言之,只要在JavaScript中执行正则表达式,就会在RegExp
构造函数上为某些属性赋值。例如:
/foo/.test('football')
//-> true
RegExp.input
//-> "football"
RegExp.rightContext
//-> "tball"
我想在不影响这些属性的情况下执行正则表达式。如果那是不可能的(我认为不可能),我想至少将它们恢复到以前的值。
我知道input
/ $_
是可写的,但其他大多数都不是,似乎。一种选择可能是重建一个重新应用所有这些值的正则表达式,但我认为这将非常困难。
我想要这个的原因是因为我正在编写shim of a native API,并使用test262套件对其进行测试。 test262套件在某些测试中失败,它会检查RegExp对象是否具有这些属性的意外值。
答案 0 :(得分:1)
这是最终结果。它比我最初的努力更强大;它正确地转义子表达式,确保它们以正确的顺序出现,并且在找到空表达式时不会停止:
/**
* Constructs a regular expression to restore tainted RegExp properties
*/
function createRegExpRestore () {
var lm = RegExp.lastMatch,
ret = {
input: RegExp.input
},
esc = /[.?*+^$[\]\\(){}|-]/g,
reg = [],
cap = {};
// Create a snapshot of all the 'captured' properties
for (var i = 1; i <= 9; i++)
cap['$'+i] = RegExp['$'+i];
// Escape any special characters in the lastMatch string
lm = lm.replace(esc, '\\$0');
// Now, iterate over the captured snapshot
for (var i = 1; i <= 9; i++) {
var m = cap['$'+i];
// If it's empty, add an empty capturing group
if (!m)
lm = '()' + lm;
// Else find the escaped string in lm wrap it to capture it
else
lm = lm.replace(m.replace(esc, '\\$0'), '($0)');
// Push to `reg` and chop `lm`
reg.push(lm.slice(0, lm.indexOf('(') + 1));
lm = lm.slice(lm.indexOf('(') + 1);
}
// Create the property-reconstructing regular expression
ret.exp = RegExp(reg.join('') + lm, RegExp.multiline ? 'm' : '');
return ret;
}
它做了我原本认为困难的事情。这应该将所有属性恢复为以前的值,如果你这样使用它:
var
// Create a 'restore point' for RegExp
old = createRegExpRestore(),
// Run your own regular expression
test = someOtherRegEx.test(someValue);
// Restore the previous values by running the RegExp
old.exp.test(old.input);
答案 1 :(得分:1)
您可以尝试为测试创建包装函数:
var fTest = RegExp.test;
RegExp.test = function() {
var bReturn = fTest.apply(RegExp, arguments);
delete RegExp.input;
delete RegExp.rightContext;
return bReturn;
}