javascript - regexp exec internal index doesn't progress if first char is not a match

无人久伴 提交于 2021-01-28 05:06:53

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!