我需要匹配组中不以“ /”开头的数字。

为了做到这一点,我做了以下正则表达式:

var reg = /(^|[^,\/])([0-9]*\.?[0-9]*)/g;


第一部分匹配字符串的开头,除“ /”以外的其他任何内容,第二部分匹配数字。关于正则表达式的一切正常(它符合我的需求)。我使用https://regex101.com/进行测试。此处的示例: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

或者,您可以使用另一个“技巧”,如果没有匹配项,则手动前进正则表达式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);

07-24 09:38
查看更多