Javascript 为什么带有全局标志的RegExp会给出错误的结果?

Javascript 为什么带有全局标志的RegExp会给出错误的结果?,javascript,regex,Javascript,Regex,当我使用全局标志和不区分大小写标志时,这个正则表达式有什么问题?查询是用户生成的输入。结果应该是[真的,真的] 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; 对于(i=

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

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;
对于(i=0;i++<10;)

控制台日志(注册测试(“a”)
您正在使用单个
RegExp
对象并多次执行它。在每次连续执行时,它将从最后一个匹配索引继续执行

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

result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
// result is now [true, true]
尽管如此,每次创建一个新的RegExp对象可能更具可读性(由于RegExp是缓存的,所以开销最小):


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

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

result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
// result is now [true, true]
尽管如此,每次创建一个新的RegExp对象可能更具可读性(由于RegExp是缓存的,所以开销最小):


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

!!'Foo Bar'.match(re); // -> true
!!'Foo Bar'.match(re); // -> true
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
注意:
将其转换为布尔值,然后反转布尔值以反映结果

或者,您可以只重置
lastIndex
属性:

!!'Foo Bar'.match(re); // -> true
!!'Foo Bar'.match(re); // -> true
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));

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

!!'Foo Bar'.match(re); // -> true
!!'Foo Bar'.match(re); // -> true
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));
注意:
将其转换为布尔值,然后反转布尔值以反映结果

或者,您可以只重置
lastIndex
属性:

!!'Foo Bar'.match(re); // -> true
!!'Foo Bar'.match(re); // -> true
result.push(re.test('Foo Bar'));
re.lastIndex = 0;
result.push(re.test('Foo Bar'));

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

var查询='foob';
var re=new RegExp(查询'gi');
var结果=[];
结果.推(重新测试('Foo-Bar'));
警报(关于最新索引);

结果.推(重新测试('Foo-Bar'))
带有
g
标志的
RegExp
对象跟踪匹配发生的位置,因此在后续匹配中,它将从上次使用的索引开始,而不是从0开始。看一看:

var查询='foob';
var re=new RegExp(查询'gi');
var结果=[];
结果.推(重新测试('Foo-Bar'));
警报(关于最新索引);

结果.推(重新测试('Foo-Bar'))
删除全局
g
标志将解决您的问题

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


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

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


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

在首次搜索之前:

myRegex.lastIndex
//is 0
在第一次搜索之后

myRegex.lastIndex
//is 8

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

使用/g标志告诉它在点击后继续搜索

在首次搜索之前:

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
延迟效应。它的工作原理与我预期的一样。

我有以下功能:

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查询='foob';
var re=new RegExp(查询'gi');
var结果=[];
结果.推(重新测试('Foo-Bar'));
re.lastIndex=0;
结果.推(重新测试('Foo-Bar'));

console.log(result)
您需要设置re.lastIndex=0,因为使用g标志regex跟踪发生的最后一次匹配,所以test不会去测试相同的字符串,因为您需要执行re.lastIndex=0

var查询='foob';
var re=new RegExp(查询'gi');
var结果=[];
结果.推(重新测试('Foo-Bar'));
re.lastIndex=0;
结果.推(重新测试('Foo-Bar'));

log(result)
欢迎使用JavaScript中RegExp的众多陷阱之一。它有我见过的最糟糕的正则表达式处理接口之一,充满了奇怪的副作用和模糊的警告。您通常希望使用regex执行的大多数常见任务都很难正确拼写。XRegExp看起来是一个不错的选择。这里也可以看到答案:如果你能侥幸逃脱,一个解决方案是直接使用regex文本,而不是将其保存到
re
。欢迎使用JavaScript中RegExp的众多陷阱之一。它有我见过的最糟糕的正则表达式处理接口之一,充满了奇怪的副作用和模糊的警告。大部分的com