我应该使用\ d或[0-9]来匹配Perl正则表达式中的数字吗?

Bea*_*ano 47 regex perl

在过去几周阅读了一些问题/答案后,我看到\dperl正则表达式的使用被评论为不正确.正如在perl的更高版本中\d不同[0-9],因为\d它将表示具有digit属性的任何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
Run Code Online (Sandbox Code Playgroud)

mir*_*rod 57

在我看来,使用\d它非常危险,在语言中这是一个糟糕的设计决定,就像你想要的大多数情况一样[0-9].霍夫曼编码将决定使用\dASCII数字.

大多数以前的海报都已经强调了你应该使用的原因[0-9],所以让我给你一些更多的数据:

  • 如果我正确地读取了unicode图表' ??'是一个数字(70表示,请不要相信我的话).

  • 试试这个:

    $ perl -le '$one = chr 0xFF11; print "$one + 1 = ", $one+1;'
    ? + 1 = 1
    
    Run Code Online (Sandbox Code Playgroud)
  • 以下是有效数字的部分列表(可能会或可能不会在浏览器中正确显示,具体取决于您使用的字体),对于每个数字,只有第一个被解释为使用Perl进行算术运算时的数字,如如上所示:

     ZERO:  0???????????????
     ONE:   1???????????????
     TWO:   2???????????????
     THREE: 3???????????????
     FOUR:  4???????????????
     FIVE:  5???????????????
     SIX:   6???????????????
     SEVEN: 7???????????????
     EIGHT: 8???????????????
     NINE:  9?????????????????
    
    Run Code Online (Sandbox Code Playgroud)

你还不相信吗?

  • 该列表+1!我开始怀疑那里有哪些其他数字. (7认同)
  • 如果 Perl 到目前为止已经接受了 UNICODE,那么它似乎应该走完剩下的路并处理所有数字。当然,这种方式是疯狂的,但疯狂不是所有 Perl 程序员的命运 ;-) 吗? (2认同)
  • @Beano我不是说不要用\ d; 我的意思是当你的意思是[0-9]时不要使用\ d.当你的意思是[]时,它类似于不使用\ s.问题归结为你是否介意匹配⑤以及5? (2认同)

Nic*_*ght 40

为了最大限度地提高安全性,我建议[0-9]您在没有特别打算匹配所有unicode定义的数字时使用.

Per perldoc perluniintro,Perl不支持使用数字以外的[0-9]数字,所以[0-9]如果以下两者都是真的,我肯定会使用它:

  1. 您希望将结果用作数字(例如对其执行数学运算或将其存储在仅接受正确数字的位置(例如,数据库中的INT列)).

  2. [^0-9]数据中可能存在非数字,正则表达式可以匹配它们.(请注意,对于不受信任/恶意的输入,应始终将此视为真.)

如果这些都是假的,只会有很少有理由专门不能使用\d(你可能会能够告诉的时候是这样的话),如果你匹配所有Unicode定义的数字,你"我肯定想用\d.

  • 如果应用于Unicode字符串,\ d确实可以匹配10个以上的不同字符. (3认同)

Jon*_*ler 8

根据perlreref,' \d'是区域设置感知和Unicode感知.

但是,如果您使用的代码集不是Unicode,那么您不必担心Unicode数字,如果您使用的代码集类似于Latin-1(ISO 8859-1或8859-15),然后,语言环境感知不会伤害到你,因为代码集不包含任何其他数字字符.

因此,对于许多人来说,在很多时候,你可以\d毫无顾虑地使用' '.但是,如果Unicode数据是您工作的一部分,那么您需要更仔细地考虑您的身份.


Cha*_*ens 5

就像从轨道上钻取网站一样,[0-9]是唯一可以确定的方法.是的,它很难看.是的,选择\dUNICODE和语言环境是愚蠢的.但这是我们的床,我们必须躺在床上.

至于人们在沙滩上低头说它不影响他们今天使用的字符集,你今天可能正在使用这个字符集,但世界其他地方现在正在使用UTF-8而你将成为尽快使用它.请记住代码就像维护你的代码的人是一个知道你住在哪里的杀人狂.

哦,至于使用\dvs的Perl模块[0-9],即使核心仍然存在UNICODE问题.

如果你确实意味着任何数字,但希望能够对结果进行数学运算,你可以使用Text::Unidecode:

#!/usr/bin/perl

use strict;
use warnings;

use Text::Unidecode;

my $number = "\x{1811}\x{1812}\x{1813}\x{1814}\x{1815}";
print "$number is ", unidecode($number), "\n";
Run Code Online (Sandbox Code Playgroud)

经过一些测试后,看起来Text :: Unidecode不能正确处理所有数字字符.我正在编写一个可行的模块.