Regex 我应该使用\d或[0-9]来匹配Perl正则表达式中的数字吗?
在过去的几周里,我阅读了大量的问题/答案,发现在perl正则表达式中使用Regex 我应该使用\d或[0-9]来匹配Perl正则表达式中的数字吗?,regex,perl,Regex,Perl,在过去的几周里,我阅读了大量的问题/答案,发现在perl正则表达式中使用\d被评论为不正确。在更高版本的perl中,\d与[0-9]不同,因为\d将表示任何具有数字属性的Unicode字符,[0-9]表示字符“0”、“1”、“2”、“9” 我理解,在某些情况下,[0-9]将是正确的使用方法,而在其他情况下,\d将是正确的使用方法。我想知道人们认为使用哪个默认值是正确的 就我个人而言,我觉得\d表示法非常简洁和富有表现力,而相比之下[0-9]有点麻烦。但我在编写多语言代码方面没有什么经验,更确切地
\d
被评论为不正确。在更高版本的perl中,\d
与[0-9]
不同,因为\d
将表示任何具有数字属性的Unicode字符,[0-9]
表示字符“0”、“1”、“2”、“9”
我理解,在某些情况下,[0-9]
将是正确的使用方法,而在其他情况下,\d
将是正确的使用方法。我想知道人们认为使用哪个默认值是正确的
就我个人而言,我觉得\d
表示法非常简洁和富有表现力,而相比之下[0-9]
有点麻烦。但我在编写多语言代码方面没有什么经验,更确切地说,是为不适合ASCII字符范围的语言编写代码,因此可能有些幼稚
我注意到
$find /System/Library/Perl/5.8.8/ -name \*pm | xargs grep '\\d' | wc -l
298
$find /System/Library/Perl/5.8.8/ -name \*pm | xargs grep '\[0-9\]' | wc -l
26
我觉得两者都有各自的位置。然而,99.999%的时间(特别是在我封闭的美国合作大世界里)它们是可以互换的。我每天都使用perl来处理数据,在我处理的所有数据集中都没有不符合
[0-9]
的数字。然而,我非常理解\d
和[0-9]
之间有一个重要的区别,意识到这一区别是很好的。我使用\d
是因为它看起来更简洁(如您所说),而且在我的数据处理小世界中永远不会“错”。为了最大的安全性,我建议在您不打算特别匹配所有unicode定义的数字时使用[0-9]
根据perldoc的说法,Perl不支持使用除[0-9]
以外的数字作为数字,因此如果以下两种情况都成立,我肯定会使用[0-9]
:
[^0-9]
,正则表达式可以匹配这些数字。(请注意,对于不可信/恶意输入,应始终将此项视为正确。)如果其中任何一个都是错误的,那么很少有理由明确不使用
\d
(并且您可能会知道什么时候是这种情况),如果您试图匹配所有unicode定义的数字,那么如果您将\d
应用于unicode字符串(例如“\X),您肯定会希望使用\d
{660}“=~/\d/
),它将匹配一个Unicode数字。如果将\d
应用于二进制字符串(如上面的UTF-8等价物:“\xd9\xa0”=~/\d/
),它将只匹配10个ASCII数字。Perl 5.8默认情况下不会创建Unicode字符串(除非您特别要求,如“\X{…}”
或使用utf8;
等)
因此,我的建议是:如果应用程序使用Unicode字符串,只需注意\d
和[0-9]
之间的区别。根据,“\d
”是区域设置感知和Unicode感知的
但是,如果您使用的代码集不是Unicode,那么您就不必担心Unicode数字,如果您使用的代码集类似于Latin-1(ISO 8859-1或8859-15),那么区域设置意识也不会伤害您,因为代码集不包含任何其他数字字符
<>所以,对于很多人来说,大部分时间,你可以不用关注“<代码> \d<代码>”。但是,如果Unicode数据是你工作的一部分,那么你需要更仔细地考虑你所追求的东西。 < P>就像从轨道上核对站点,<代码> [09]是唯一可以确定的方法。是的,这很难看。是的,选择将
\d
设置为UNICODE和区域设置是愚蠢的。但这是我们的床,我们必须躺在床上
至于那些把头埋在沙子里说这不会影响他们今天使用的角色集的人,你今天可能正在使用这个角色集,但是世界上其他地方现在正在使用UTF-8,你很快也会使用它。记住要像维护你的代码的人是一个知道你在哪里的杀人狂一样编写代码ve
哦,至于使用\d
vs[0-9]
的Perl模块,即使是核心也有
如果您实际上是指任何数字,但希望能够对结果进行数学运算,您可以使用:
经过更多的测试,似乎Text::Unidecode无法正确处理所有数字字符。我正在编写一个可以正常工作的脚本。在我看来,使用
\d
非常危险,这是一个糟糕的语言设计决策,因为在大多数情况下,您需要[0-9]
。哈夫曼编码将规定对ASCII数字使用\d
之前的大多数海报已经强调了为什么您应该使用[0-9]
,所以让我再给您一些数据:
- 如果我正确阅读unicode图表,“
”是一个数字(印度字母70,不要相信我的话)۷۰
- 试试这个:
$ perl -le '$one = chr 0xFF11; print "$one + 1 = ", $one+1;' 1 + 1 = 1
- 下面是每个数字的部分有效数字列表(根据您使用的字体,这些数字可能会在浏览器中正确显示,也可能不会正确显示),在使用Perl进行算术运算时,只有第一个数字会被解释为数字,如上所示:
ZERO: 0٠۰߀०০੦૦୦௦౦೦൦๐໐0 ONE: 1١۱߁१১੧૧୧௧౧೧൧๑໑1 TWO: 2٢۲߂२২੨૨୨௨౨೨൨๒໒2 THREE: 3٣۳߃३৩੩૩୩௩౩೩൩๓໓3 FOUR: 4٤۴߄४৪੪૪୪௪౪೪൪๔໔4 FIVE: 5٥۵߅५৫੫૫୫௫౫೫൫๕໕5 SIX: 6٦۶߆६৬੬૬୬௬౬೬൬๖໖6 SEVEN: 7٧۷߇७৭੭૭୭௭౭೭൭๗໗7 EIGHT: 8٨۸߈८৮੮૮୮௮౮೮൮๘໘8 NINE: 9٩۹߉९৯੯૯୯௯౯೯൯๙໙9��
你还不相信吗?如果
[0-9]
觉得笨重,也许你可以定义:$d=qr/[0-9]/;
并用它代替\d
随着数据格式控件的增加,对模式特异性的需求降低了
例如,如果要匹配机器生成的数据,并且始终遵循相同的输出格式规则,则无需如此精确。
以IPv4地址为例
ZERO: 0٠۰߀०০੦૦୦௦౦೦൦๐໐0
ONE: 1١۱߁१১੧૧୧௧౧೧൧๑໑1
TWO: 2٢۲߂२২੨૨୨௨౨೨൨๒໒2
THREE: 3٣۳߃३৩੩૩୩௩౩೩൩๓໓3
FOUR: 4٤۴߄४৪੪૪୪௪౪೪൪๔໔4
FIVE: 5٥۵߅५৫੫૫୫௫౫೫൫๕໕5
SIX: 6٦۶߆६৬੬૬୬௬౬೬൬๖໖6
SEVEN: 7٧۷߇७৭੭૭୭௭౭೭൭๗໗7
EIGHT: 8٨۸߈८৮੮૮୮௮౮೮൮๘໘8
NINE: 9٩۹߉९৯੯૯୯௯౯೯൯๙໙9��
'ip\haddress\h(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\D'