为什么这个正则表达式允许插入符号?

时间:2015-04-21 12:13:03

标签: regex

http://regexr.com/3ars8

^(?=.*[0-9])(?=.*[A-z])[0-9A-z-]{17}$

应该匹配“17个字母数字字符,也允许使用连字符,必须包含至少一个字母和至少一个数字”

它将正确匹配:

ABCDF31U100027743

并正确拒绝匹配:

AB$DF31U100027743

(以及几乎所有其他非字母数字字符)

但显然会允许:

AB^DF31U100027743

3 个答案:

答案 0 :(得分:139)

因为您的角色类[A-z]与此符号匹配。

[A-z]匹配[\]^_`和英文字母。

实际上,这是一个常见的错误。您应该使用[a-zA-Z]代替只允许使用英文字母。

以下是来自Expresso的可视化,显示[A-z]实际涵盖的范围:

screenshot from Expresso showing the ASCII table, where you can see what the [A-z] range actually covers

因此,this regex(带有i选项)无法捕获您的字符串。

^(?=.*[0-9])(?=.*[a-z])[0-9a-z-]{17}$

在我看来,使用Ignorecase选项来避免这样的问题并缩短正则表达式总是更安全。

答案 1 :(得分:15)

  

正则表达式使用从空格到波浪范围的ASCII可打印字符。

每当我们使用[A-z]令牌时,它都会匹配下表突出显示的字符。如果我们使用[ -~]令牌,则会从SPACE开始匹配到代字号。

enter image description here

答案 2 :(得分:5)

你允许使用A-z(资本' A'通过更低的' z')。你不会说你正在使用的正则表达式包,但是A-Z和a-z是连续的并不一定清楚;中间可能还有其他角色。试试这个:

^(?=.*[0-9])(?=.*[A-Za-z])[0-9A-Za-z-]{17}$

在regexpal中似乎符合你的标准。