gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 04:11:32 31 4
gpt4 key购买 nike

我正在尝试从字符串中提取数字组。这些数字可以单独存在,也可以作为 \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,3,148,14 到 31 - 随机字符串 46 随机字符串 将返回值 17;3;148;14 到 31;46,而 46 不应匹配。

我并不真正关心结果的格式,因为无论如何我都会在之后对其进行清理,因此 '03 ' 返回为 '03' 并不重要'03'。对于数字范围也是如此,15 - 17 可以返回为 15 - 17,或者像上面的示例一样,使用捕获组来确定上限和下限绑定(bind),但我仍然需要能够判断两个数字是独立的还是一个范围,因此 5,8,10-12 不能返回为 5;8;10;12 .

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

如果有可能,并且这纯粹是可选的,我还想保留最后一个数字范围之后的字符串,例如STR 14, 23 Some String 18 Some other string 应在 14;23 中返回,并单独返回 Some String 18 Some other string

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

最佳答案

这是我的尝试。

[
'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',
'14 ~ 16',
'Random String 15',
'1to3',
'M-01 to STR 6',
'17 56'
].forEach(function(str) {
var rangeRe = /(?:\s*,\s*)(?:M-|STR )?(\d+)(?:\s*(?:-|~|to)\s*(\d+))?/g,
ranges = [],
lastIndex = 1,
match;

str = ',' + str;

while (match = rangeRe.exec(str)) {
// Push a lower and upper bound onto the list of ranges
ranges.push([+match[1], +(match[2] || match[1])]);

lastIndex = rangeRe.lastIndex;
}

// Log the original string, the ranges and the remainder
console.log([
str.slice(1),
ranges.map(function(pair) {
return pair[0] + '-' + pair[1];
}).join(' ; '),
str.slice(lastIndex)
]);
});

以下是我遵循的规则:

  • 数字由连续数字组成。
  • 范围由单个数字或一对数字组成。
  • 如果某个范围包含一对,则它们可以用 - 分隔。 , ~to ,加上分隔符两侧的任意空格。
  • 范围(注意范围,而不是数字)可以以 M- 为前缀。或STR 。前缀和范围之间不允许有额外的空格。
  • 范围由 , 分隔在 , 两侧加上任意空格.

每个范围都被解析为由下限和上限组成的数组对。对于单个数字范围,两个边界使用相同的值。

我使用了 exec 的有状态性。循环的每次迭代都从上一次匹配结束的地方开始匹配。 lastIndex被跟踪,以便我们可以在最后生成剩余的“随机字符串”。

我添加了一个,在开始之前先从字符串的前面出来。这允许 RegExp 假设所有范围都以 , 开头。 ,避免需要第一个范围的特殊情况。

与您发布的一些正则表达式的一个关键区别是,我将整个“范围分隔符和上限”部分作为一个单元作为可选,而不是使它们单独可选。其结果是像 17 56 这样的输入将对待 56作为“随机字符串”而不是上限。该范围将被视为 17-17。

关于javascript - 全局正则表达式匹配停止中间字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46229382/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com