当我使用全局标志和大小写不敏感标志时,这个正则表达式有什么问题?查询是用户生成的输入。结果应该是[真,真]。

var query = 'Foo B';
var re = new RegExp(query, 'gi');
var result = [];
result.push(re.test('Foo Bar'));
result.push(re.test('Foo Bar'));
// result will be [true, false]

var reg = /^a$/g; for(i = 0; i++ < 10;) console.log(reg.test(“a”));


您正在使用一个RegExp对象并多次执行它。在每次连续执行时,它都从最后一个匹配索引开始。

你需要在每次执行前“重置”正则表达式,从头开始:

result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
// result is now [true, true]

话虽如此,每次创建一个新的RegExp对象可能更具可读性(开销很小,因为RegExp是缓存的):

result.push((/Foo B/gi).test(stringA));
result.push((/Foo B/gi).test(stringB));

test更新正则表达式的lastIndex属性,以便每次测试都从上次测试停止的位置开始。我建议使用String.prototype.match,因为它不会更新lastIndex属性:

!!'Foo Bar'.match(re); // -> true
!!'Foo Bar'.match(re); // -> true

注意:! !将其转换为布尔值,然后反转布尔值,以反映结果。

或者,你可以重置lastIndex属性:

result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));

带有g标志的RegExp对象跟踪发生匹配的lastIndex,因此在后续匹配中,它将从最后使用的索引开始,而不是0。来看看:

var query = 'Foo B'; var re = new RegExp(查询,'gi'); console.log (re.lastIndex); console.log(再保险。测试(Foo酒吧)); console.log (re.lastIndex); console.log(再保险。测试(Foo酒吧)); console.log (re.lastIndex);

如果您不想在每次测试后手动将lastIndex重置为0,只需删除g标志。

下面是规范规定的算法(章节15.10.6.2):

RegExp.prototype.exec(字符串) 执行 字符串的正则表达式匹配 针对正则表达式和 返回一个数组对象 匹配的结果,或null string did not match字符串 ToString(string)用于搜索 正则表达式的出现 模式如下:

Let R be this RexExp object. Let S be the value of ToString(string). Let length be the length of S. Let lastIndex be the value of the lastIndex property on R. Let i be the value of ToInteger(lastIndex). If the global property is false, let i = 0. If i < 0 or i > length then set the lastIndex property of R to 0 and return null. Call [[Match]], giving it the arguments S and i. If [[Match]] returned failure, go to step 9; otherwise let r be its State result and go to step 10. Let i = i+1. Go to step 7. Let e be r's endIndex value. If the global property is true, set the lastIndex property of R to e. Let n be the length of r's captures array. (This is the same value as 15.10.2.1's NCapturingParens.) Return a new array with the following properties: The index property is set to the position of the matched substring within the complete string S. The input property is set to S. The length property is set to n + 1. The 0 property is set to the matched substring (i.e. the portion of S between offset i inclusive and offset e exclusive). For each integer i such that i > 0 and i ≤ n, set the property named ToString(i) to the ith element of r's captures array.


删除全局g标志将解决您的问题。

var re = new RegExp(query, 'gi');

应该是

var re = new RegExp(query, 'i');

使用/g标志告诉它在命中后继续搜索。

如果匹配成功,exec()方法返回一个数组并更新正则表达式对象的属性。

在你第一次搜索之前:

myRegex.lastIndex
//is 0

第一次搜索之后

myRegex.lastIndex
//is 8

删除g,它将在每次调用exec()后退出搜索。


函数是:

function parseDevName(name) {
  var re = /^([^-]+)-([^-]+)-([^-]+)$/g;
  var match = re.exec(name);
  return match.slice(1,4);
}

var rv = parseDevName("BR-H-01");
rv = parseDevName("BR-H-01");

第一个电话起作用了。 第二个电话没有。切片操作抱怨一个空值。我认为这是因为re.lastIndex。这很奇怪,因为我希望每次调用函数时都分配一个新的RegExp,而不是在函数的多次调用之间共享。

当我把它改成:

var re = new RegExp('^([^-]+)-([^-]+)-([^-]+)$', 'g');

然后我就不会得到lastIndex延迟效应。正如我所期望的那样。


你需要设置re.lastIndex = 0,因为带有g标志的regex会跟踪最近发生的匹配,所以test不会去测试相同的字符串,为此你需要执行re.lastIndex = 0

var query = 'Foo B'; var re = new RegExp(查询,'gi'); Var结果= []; result.push(再保险。测试(Foo酒吧)); re.lastIndex = 0; result.push(再保险。测试(Foo酒吧)); console.log(结果)