问题
I need to match numbers that are not preceeded by "/" in a group.
In order to do this I made the following regex:
var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;
First part matches start of the string and anything else except "/", second part matches a number. Everything works ok regarding the regex (it matches what I need). I use https://regex101.com/ for testing. Example here: https://regex101.com/r/7UwEUn/1
The problem is that when I use it in js (script below) it goes into an infinite loop if first character of the string is not a number. At a closer look it seems to keep matching the start of the string, never progressing further.
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]});
}
}
If the string starts with a number ("1 a b") all is fine.
The problem appears to be here (^|[^,/]) - removing ^| will fix the issue with infinite loop but it will not match what I need in strings starting with numbers.
Any idea why the internal index is not progressing?
回答1:
Infinite loop is caused by the fact your regex can match an empty string. You are not likely to need empty strings (even judging by your code), so make it match at least one digit, replace the last *
with +
:
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);
Note that this regex will not match numbers like 34.
and in that case you may use /(^|[^,\/])([0-9]*\.?[0-9]+|[0-9]*\.)/g
, see this regex demo.
Alternatively, you may use another "trick", advance the regex lastIndex
manually upon no match:
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);
来源:https://stackoverflow.com/questions/46587762/javascript-regexp-exec-internal-index-doesnt-progress-if-first-char-is-not-a