javascript - 如果第一个字符不匹配,regexp exec 内部索引不会进行
javascript - regexp exec internal index doesn't progress if first char is not a match
我需要匹配组中不以“/”开头的数字。
为了做到这一点,我制作了以下正则表达式:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;
第一部分匹配字符串的开头和除“/”以外的任何其他内容,第二部分匹配数字。关于正则表达式,一切正常(它符合我的需要)。我用 https://regex101.com/ for testing. Example here: https://regex101.com/r/7UwEUn/1
问题是,当我在 js(下面的脚本)中使用它时,如果字符串的第一个字符不是数字,它会进入无限循环。仔细一看,它似乎一直在匹配字符串的开头,再也没有继续前进。
var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;
var text = "a 1 b";
while (match = reg.exec(text)) {
if (typeof match[2] != 'undefined' && match[2] != '') {
numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
}
如果字符串以数字 ("1 a b") 开头,则一切正常。
问题似乎出在此处 (^|[^,/]) - 删除 ^|将解决无限循环的问题,但它与我需要的以数字开头的字符串不匹配。
知道为什么内部索引没有进展吗?
无限循环是由于您的正则表达式可以匹配空字符串造成的。你不太可能需要空字符串(即使根据你的代码判断),所以让它至少匹配一个数字,将最后一个 *
替换为 +
:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]+)/g;
var text = "a 1 b a 2 ana 1/2 are mere (55";
var numbers=[];
while (match = reg.exec(text)) {
numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
console.log(numbers);
请注意,此正则表达式不会匹配 34.
这样的数字,在这种情况下,您可以使用 /(^|[^,\/])([0-9]*\.?[0-9]+|[0-9]*\.)/g
,请参阅 this regex demo。
或者,您可以使用另一个 "trick",在不匹配时手动推进正则表达式 lastIndex
:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]+)/g;
var text = "a 1 b a 2 ana 1/2 are mere (55";
var numbers=[];
while (match = reg.exec(text)) {
if (match.index === reg.lastIndex) {
reg.lastIndex++;
}
if (match[2]) numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
console.log(numbers);
我需要匹配组中不以“/”开头的数字。
为了做到这一点,我制作了以下正则表达式:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;
第一部分匹配字符串的开头和除“/”以外的任何其他内容,第二部分匹配数字。关于正则表达式,一切正常(它符合我的需要)。我用 https://regex101.com/ for testing. Example here: https://regex101.com/r/7UwEUn/1
问题是,当我在 js(下面的脚本)中使用它时,如果字符串的第一个字符不是数字,它会进入无限循环。仔细一看,它似乎一直在匹配字符串的开头,再也没有继续前进。
var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;
var text = "a 1 b";
while (match = reg.exec(text)) {
if (typeof match[2] != 'undefined' && match[2] != '') {
numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
}
如果字符串以数字 ("1 a b") 开头,则一切正常。
问题似乎出在此处 (^|[^,/]) - 删除 ^|将解决无限循环的问题,但它与我需要的以数字开头的字符串不匹配。
知道为什么内部索引没有进展吗?
无限循环是由于您的正则表达式可以匹配空字符串造成的。你不太可能需要空字符串(即使根据你的代码判断),所以让它至少匹配一个数字,将最后一个 *
替换为 +
:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]+)/g;
var text = "a 1 b a 2 ana 1/2 are mere (55";
var numbers=[];
while (match = reg.exec(text)) {
numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
console.log(numbers);
请注意,此正则表达式不会匹配 34.
这样的数字,在这种情况下,您可以使用 /(^|[^,\/])([0-9]*\.?[0-9]+|[0-9]*\.)/g
,请参阅 this regex demo。
或者,您可以使用另一个 "trick",在不匹配时手动推进正则表达式 lastIndex
:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]+)/g;
var text = "a 1 b a 2 ana 1/2 are mere (55";
var numbers=[];
while (match = reg.exec(text)) {
if (match.index === reg.lastIndex) {
reg.lastIndex++;
}
if (match[2]) numbers.push({'index': match.index + match[1].length, 'value': match[2]});
}
console.log(numbers);