将错就错?正则表达式 [,-.]


正则表达式 [,-.]其目的很清楚:匹配两组由逗号、破折号或句号分隔的两个数字。
当然,它不应该起作用。
字符类中的破折号很特别,因为它们用于范围(如[a-z]用于匹配小写ASCII字母)。
如果你想在一个字符类中使用"-",你应该把它放在开头或结尾,而不是放在中间。所以这应该是[-,.]而不是[,-.]。

我以为[,-.]是个错字,它不会与-相匹配,但我找不到一个错误。事实上,它工作得很好,你可以自己试试。

$ perl -E 'say "ok" if "12-34" =~ /\d{2}[,-.]\d{2}/'
ok

发生了什么事?
逗号、破折号和句号在ASCII中是紧挨着的。
因此,抓取从,到.的所有字符也包括-,而不包括其他。[,-.]是唯一可能的字符类,中间有一个-,只匹配-。
只适合匹配字符类的开头或结尾的。

另外一种解释:因为破折号将其变成范围运算符(如 0-9),而破折号位于 ASCII 表中的逗号和点之间。
这是一场巧合避免的灾难。那好美丽。