1

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 Answer 1

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);

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.