是否有正则表达式可以将 10 位数字(通常是非连续的)放入命名的捕获组中?

Is there a regex that will put 10 digits (usually non-consecutive) into a named capturing group?

提问人:Hoshi 提问时间:10/13/2023 更新时间:10/13/2023 访问量:81

问:

我有一个用户输入字符串,它应该包含至少 10 位数字,但它们可能是非连续的。在这些可能的用户输入中:

"What is 12? Can we 345 the loan to 678-90"
">>123456789--0"
"1234567890541112144847-909"
"Maybe try 123456 with 7890 too"

我想要一个正则表达式给我.match.groups.anyTen = '1234567890'

我已经尝试过,但我无法将匹配项合并到一个命名组中。 仅命名连续数字的第一个匹配项。/\d+/g/(?<anyTen>\d+/g

其他故障:

/(?<anyTen>\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*)/
/(?<anyTen>\d{1,10})/
/(?<anyTen>\D*(\d\D*){10})/
javascript 则表达 式 正则表达式组

评论

0赞 Wyck 10/13/2023
这被表述为 XY 问题。无需生成具有非连续字符的捕获组即可获得所需的结果。在匹配之前或之后,明智地使用一些方法来消除不需要的字符似乎是合理的。也许你的问题应该改写,以说明你的字符串处理目标,而不承诺使用正则表达式。replace
0赞 Hoshi 10/14/2023
@Wyck这不是一个坏观点,但我想尽可能地使用正则表达式,并认为我只是错过了一些关于使用反向引用或类似的东西。所以,是的,一个简单的人就可以做到了,但我的正则表达式知识就会停滞不前。.replaceAll(/\D/g,'').substring(0,9);

答:

3赞 The fourth bird 10/13/2023 #1

不能有一个由非连续匹配项组成的组。

您可以做的是匹配前 10 位数字,然后从中删除非数字。

请注意,这也与换行符匹配。\D

如果您想要 10 位或更多位数字,量词将变为{9,}

const s = `"What is 12? Can we 345 the loan to 678-90"
">>123456789--0"
"1234567890541112144847-909"
"Maybe try 123456 with 7890 too"`;

const regex = /^[^\d\n]*(?<anyTen>\d(?:[^\d\n]*\d){9})/gm;
const result = Array.from(
  s.matchAll(regex), m =>
  m.groups.anyTen.replace(/\D+/g, "")
);
console.log(result)

另一种选择是覆盖 groups.anyVal 属性的值:

const s = "What is 12? Can we 345 the loan to 678-90";
const regex = /^[^\d\n]*(?<anyTen>\d(?:[^\d\n]*\d){9})/;
const result = regex.exec(s);

if (result) {
  result.groups.anyTen = result.groups.anyTen.replace(/\D+/g, "");
  console.log(result.groups.anyTen);
}

评论

1赞 Hoshi 10/14/2023
这些都很棒,如果我必须运行 2 个顺序正则表达式,那很好,另外 4 毫秒是多少?我曾希望使用反向引用可以代替后处理步骤,但我显然不是一个正则表达式。谢谢!
0赞 Ale_Bianco 10/13/2023 #2

您可以使用以下正则表达式模式:

(?<anyTen>(?:\D*\d){10,})
  • (?<anyTen> ... ):这是一个名为“anyTen”的命名捕获组。
  • (?: ... ):这是一个非捕获组。它允许我们对模式进行分组,而无需创建单独的捕获组。
  • \D*:匹配零个或多个非数字字符。
  • \d:匹配数字。
  • {10,}:与前一个模式(非数字后跟数字)匹配至少 10 次。

用法:

const input = "What is 12? Can we 345 the loan to 678-90";
const regex = /(?<anyTen>(?:\D*\d){10,})/;
const match = input.match(regex);

if (match) {
  const anyTen = match.groups.anyTen.replace(/\D/g, ''); // Remove non-digit characters
  console.log(anyTen);
} else {
  console.log("No match found.");
}

这将输出:

1234567890

评论

0赞 derpirscher 10/13/2023
您最初的陈述有点误导,因为这不是创建一个仅由数字组成的迷人组,而是从第一位到第十位数字的所有文本,您必须执行额外的步骤来删除所有非数字......而且它显然不符合 OP 的期望(这在正则表达式中是不可能的)match.groups.anyTen == "1234567890"
0赞 Hoshi 10/14/2023
哇,我真的希望这能起作用,但是:@derpirscher是正确的。运行创建了组,但具有价值"Oct 14 2023 09:10:36.251 -0400".match(/(?<anyTen>(?:\D*\d){10,})/);anyTen"Oct 14 2023 09:10:36.251 -0400"
0赞 Hoshi 10/14/2023
顺便说一句,我衷心感谢您在详细解释中付出的额外努力 - SO 礼仪的缩影!