Javascript 全局正则表达式匹配停止中间字符串

Javascript 全局正则表达式匹配停止中间字符串,javascript,regex,Javascript,Regex,我试图从字符串中提取数字组。 这些数字可以是单独的,也可以是\d+-\d+格式的范围,而两个数字之间的范围指示器可以不同,并且数字可以具有前缀M-或STR。这些组可以在给定字符串中出现1到n次,但如果组后面跟有任何不是数字、空格或上述前缀之一的字符,则匹配应该停止,即使之后可以找到更多的数字 例如,下面几行 01 05,07 05, 7 M-01, M-12 311,STR 02 M-56 STR 17 01 - Random String 25-31 Random other string M

我试图从字符串中提取数字组。 这些数字可以是单独的,也可以是
\d+-\d+
格式的范围,而两个数字之间的范围指示器可以不同,并且数字可以具有前缀
M-
STR
。这些组可以在给定字符串中出现1到n次,但如果组后面跟有任何不是数字、空格或上述前缀之一的字符,则匹配应该停止,即使之后可以找到更多的数字

例如,下面几行

01
05,07
05, 7
M-01, M-12
311,STR 02
M-56
STR 17
01 - Random String 25-31 Random other string
M-04 Random String 01
M-17,3,148,14 to 31
M-17,3,STR 148,14 to 31 - Random String
M-17,3,148,14- 31 Random, String 02 Random, other string
STR 17,3,12 to 18, 148 ,M-14- 31 : Random String 02
应该回来

01
05;07
05;7
01;12
311;02
56
17
01
04
17;3;148;14 to 31
17;3;148;14 to 31
17;3;148;14- 31
17;3;12 to 18;148;14- 31
我使用的是javascript,通过运行

var pattern = /(\d+)\s?(?:-|~|to)?\s?(\d+)?/ig
while (result = pattern.exec(line)) {console.log(result)}
但我不知道如何不匹配第一个字符串后的数字,即
M-17,3148,14到31-Random string 46 Random string
将返回值
17;3.148;14至31岁;46,而46不应匹配

我并不真正关心结果的格式,因为我一直在对它们进行消毒,所以无论
'03'
是否返回为
'03'
'03'
,都没有关系。对于数字范围也是如此,
15-17
可以作为
15-17
返回,或者像上面的例子一样,使用捕获组来确定上限和下限,但是我仍然需要能够判断两个数字是分开的还是一个范围,因此
5,8,10-12
不能作为
5返回;8.10;12

我的最终目标是提取每行中所有可能的值。在我提取了所有数字范围后,我循环遍历每个结果以获得所有可能的值,例如,5,8,10-12将变为5;8.10;11;十二,

如果有可能,而且这是完全可选的,我还希望保留最后一个数字范围之后的字符串,例如
str14,23一些字符串18一些其他字符串
应该在
14中返回;23
和单独的
一些字符串18一些其他字符串


如果有人知道如何解决这个问题,我将不胜感激。

因此,喝了一杯咖啡后,我想我找到了一个接近解决方案的办法:

function extractNumbers(line){
    var str = line.replace(/(?:M-\s?|STR )(\d+)/ig,'$1')
    var rightpart = str.match(/([a-x].*)/i)
    var leftpart = str.replace(rightpart[1],'')
    var pattern = /(\d+)\s?(?:-|~|to)?\s?(\d+)?/ig
    while (result = pattern.exec(leftpart)) {console.log(result)}
    console.log(rightpart[1])
}
此函数输出所有数字范围,然后将字符串的其余部分输出到控制台。有可能出现误报,因为它首先用数字替换所有出现的M-和STR,即使它们出现在字符串的右侧。这种精确的字符序列出现在正确部分的可能性可能很小,但仍然是


如果有人对最初的问题有一个答案,或者对如何消除误报的机会有一个想法,我很想看看。

所以,喝了一杯咖啡后,我想我找到了一个接近解决方案的办法:

function extractNumbers(line){
    var str = line.replace(/(?:M-\s?|STR )(\d+)/ig,'$1')
    var rightpart = str.match(/([a-x].*)/i)
    var leftpart = str.replace(rightpart[1],'')
    var pattern = /(\d+)\s?(?:-|~|to)?\s?(\d+)?/ig
    while (result = pattern.exec(leftpart)) {console.log(result)}
    console.log(rightpart[1])
}
此函数输出所有数字范围,然后将字符串的其余部分输出到控制台。有可能出现误报,因为它首先用数字替换所有出现的M-和STR,即使它们出现在字符串的右侧。这种精确的字符序列出现在正确部分的可能性可能很小,但仍然是

如果有人对最初的问题有一个答案,或者对如何消除误报的机会有一个想法,我很乐意看到它。

以下是我的尝试

[
'01',
'05,07',
'05, 7',
‘M-01,M-12’,
“311街02号”,
“M-56”,
‘17街’,
“01-随机字符串25-31随机其他字符串”,
'M-04随机字符串01',
‘M-17,3148,14至31’,
'M-17,3,STR 148,14至31-随机字符串',
'M-17,3148,14-31随机,字符串02随机,其他字符串',
'STR 17,3,12至18,148,M-14-31:随机字符串02',
'14 ~ 16',
'随机字符串15',
“1to3”,
“M-01至6号街”,
'17 56'
].forEach(函数(str){
变量范围=/(?:\s*,\s*)(?:M-| STR)?(\d+)(:\s*(?:-| ~ | to)\s*(\d+))/g,
范围=[],
lastIndex=1,
匹配;
str=','+str;
while(match=rangeRe.exec(str)){
//将下限和上限推到范围列表上
范围。推送([+匹配[1],+(匹配[2]|匹配[1]));
lastIndex=Range.lastIndex;
}
//记录原始字符串、范围和剩余部分
console.log([
str.slice(1),
ranges.map(函数(对){
返回对[0]+'-'+对[1];
}).join(“;”),
str.slice(lastIndex)
]);
});这是我的尝试

[
'01',
'05,07',
'05, 7',
‘M-01,M-12’,
“311街02号”,
“M-56”,
‘17街’,
“01-随机字符串25-31随机其他字符串”,
'M-04随机字符串01',
‘M-17,3148,14至31’,
'M-17,3,STR 148,14至31-随机字符串',
'M-17,3148,14-31随机,字符串02随机,其他字符串',
'STR 17,3,12至18,148,M-14-31:随机字符串02',
'14 ~ 16',
'随机字符串15',
“1to3”,
“M-01至6号街”,
'17 56'
].forEach(函数(str){
变量范围=/(?:\s*,\s*)(?:M-| STR)?(\d+)(:\s*(?:-| ~ | to)\s*(\d+))/g,
范围=[],
lastIndex=1,
匹配;
str=','+str;
while(match=rangeRe.exec(str)){
//将下限和上限推到范围列表上
范围。推送([+匹配[1],+(匹配[2]|匹配[1]));
lastIndex=Range.lastIndex;
}
//记录原始字符串、范围和剩余部分
console.log([
str.slice(1),
ranges.map(函数(对){
返回对[0]+'-'+对[1];
}).join(“;”),
str.slice(lastIndex)
]);

});这工作得非常好。比我原来的解决方案好多了。非常感谢你的努力!这非常有效。比我原来的解决方案好多了。非常感谢你的努力!