正则表达式 - 匹配一段字符范围,其量词仅匹配数字

3
我在SO上找到了一个类似的问题,但是我不能理解。这就是我需要的:
允许使用这些字符 \s\-\(\)\+ 的6位或更多位数字。
所以这是我已经有的 /^[0-9\s\-\(\)\+]{6,}$/ 问题是,我不想把除数字以外的任何东西计入6个或更多量词。如何只“计数”数字?如果我能阻止这些其他允许的字符被连续输入那就太好了,比如:
0898--234 
+43 34  434

阅读了一个小时的正则表达式速查表后,我希望有善良的人能指导我正确的方向!


1
在字符类中,您不需要转义特殊字符:[0-9\s\-\(\)\+] 可以变成 [\d\s()+-](只需将破折号“-”放在末尾即可)。 - zessx
啊,如果它们被捕获在一组括号中,我就可以逃脱它们了吗?另外,为什么破折号必须放在末尾呢? - Dan
1
@Dan 连字符是少数几个在字符类中可能具有特殊含义的字符之一:范围。将其放在末尾,它就不能表示范围,因此它没有特殊含义(即,它被视为字面量)并且不需要转义。您不必将其放在末尾,但如果不这样做,则应该转义它以避免意外指定范围。 - Wiseguy
@Wiseguy - 谢谢,我应该预料到这个问题,但有时候正则表达式还是很难的,特别是当你几周不写它们的时候。 - Dan
1
@Dan 举个例子来理解连字符和闭合括号可能存在的问题:[0-1][01-] / [}])][]})] - zessx
3个回答

4
你可以做类似于这样的事情:
/^([\s()+-]*[0-9]){6,}[\s()+-]*$/

这个正则表达式将匹配任意数量的特殊字符(空格、括号、加号或连字符),后跟一个十进制数字,重复6次或更多次,之后可以再跟任意数量的特殊字符。

如果你不想匹配两个或更多相邻的特殊字符,可以使用以下正则表达式:

/^([\s()+-]?[0-9]){6,}[\s()+-]?$/

可以使用“?”来满足禁止重复非数字标点的“好习惯”要求。 - Pointy
你可以使用/^(?:[\s()+-]?[0-9]+){6,}$/,这个正则表达式更短,但可能会导致回溯。不过性能与字符串大小直接相关。 - Casimir et Hippolyte

1

你可以使用前瞻:

/^(?=(\D*\d){6,})[0-9\s()+-]{6,}$/

第一部分非常酷。这是否意味着“零个或多个非数字字符,然后是一个数字,重复六次或更多次”? - Dan
是的,\D代表任何非数字字符,\d代表数字字符。(?=(\D*\d){6,})将确保输入中至少有6个数字。 - anubhava
1
好的,谢谢你的解释。我喜欢所有的答案,看到不同的方法来达到相同的目标对我非常有帮助。 - Dan

0
/^[\s()+-]*(\d[\s()+-]*){6,}$/

这不包括“垃圾”字符。它允许任意数量的特殊字符,后跟六次[数字后跟任意数量的特殊字符]。
如果您想在数字之间最多只有一个特殊字符,请使用?而不是*,但我假设您不太关心开头或结尾超过一个特殊字符,所以我会选择

/^[\s()+-]*(\d[\s()+-]?){6,}[\s()+-]*$/

这个正则表达式匹配任意数量的特殊字符,后面跟着6个或更多次 [一个数字后面最多跟着一个特殊字符],最后再跟着任意数量的特殊字符。


另一个选择是先从字符串中去除特殊字符,然后匹配6个或更多数字。

var rawInput = "    12  (3) -- 4 -5 ++6";
var strippedInput = rawInput.replace(/[\s()+-]*/g, "");
return new RegExp("^\d{6,}$").test(strippedInput);

请记住,您拥有完整的编程语言可供使用。我注意到人们倾向于决定使用正则表达式,然后忘记他们可以做的其他所有事情。


\d[\s()+-]? - 我喜欢这个。那是因为你可以匹配一个数字,加上0或1个特殊字符,因为有问号,对吧? - Dan
没错。问号作为量词表示一个或零个。因此,我们匹配一个数字后跟一个可选的(“一个或零个”)特殊字符。完整的正则表达式至少执行六次,并允许左右更多的特殊字符。所有答案都做类似的事情。 - SQB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接