我正在为一位同事进行代码审查,他的正则表达式如下所示:
if ($value =~ /^\d\d\d\d$/) {
#do stuff
}
Run Code Online (Sandbox Code Playgroud)
我告诉他他应该改成:
if ($value =~ /^\d{4}$/) {
#do stuff
}
Run Code Online (Sandbox Code Playgroud)
他回答说他更喜欢第一个可读性(我发现第二个更具可读性,但这是一个宗教辩论,我将保存另一天).
我的问题:一个人对另一个人有实际的好处吗?
bri*_*foy 15
没有绝对可读性这样的东西.人们可以单独认识到这一点,这就是人们经常理解他们的代码而其他人无法理解的原因.如果他从不使用量词,他总是会认为量词很难阅读,因为他从未学会理解量词.
我经常发现人们说"更具可读性",当他们真正意味着"这就是我已经知道的"或"这就是我第一次写的".但这不一定是这种情况.
像绝对量词一样{4},更容易指定并与其他程序员沟通.谁想\d用手算数?你为其他人写代码来阅读,所以不要让他们的生活更难.
但是,您可能错过了该代码中的错误,因为您专注于量词问题.该$锚允许在字符串的结尾换行,如果一个Perl的最佳实践狂热者走来,一味地增加了/xsm所有的正则表达式(一个痛苦的经验,我已经看到了几次以上),这$甚至允许更多无效的输出.您可能希望使用\z绝对字符串结束锚点.
并非它发生在您的情况下,但代码审查往往会转变为样式或语法评论(因为这些更容易注意)并且实际上忽略了检查正确和预期行为以及正确设计的重点.通常,风格问题不值得考虑考虑所有其他方法来花时间来改进代码.:)
Rob*_*Rob 12
他们完全一样,所以就实用性而言,这是一个偏好问题.这种或那种方式之间存在微小的性能差异吗?谁知道,但这肯定是微不足道的.
例如\d{12,16},当图案长度不固定时,量词更有用(和要求)\d{2,},等等.
我更喜欢\d{4}哪个更容易让我的大脑解析\d\d\d\d
如果你匹配一个字符类而不是一个简单的数字呢?[aeiouy0-9]{4}还是[aeiouy0-9][aeiouy0-9][aeiouy0-9][aeiouy0-9]?
Bra*_*ert 10
我现在要回避可读性问题.
首先让我们看一下每个版本编译的内容.
perl -Mre=debug -e'/^\d{4}$/'
Run Code Online (Sandbox Code Playgroud)
Compiling REx "^\d{4}$"
synthetic stclass "ANYOF[0-9][{unicode_all}]".
Final program:
1: BOL (2)
2: CURLY {4,4} (5)
4: DIGIT (0)
5: EOL (6)
6: END (0)
anchored ""$ at 4 stclass ANYOF[0-9][{unicode_all}] anchored(BOL) minlen 4
Freeing REx: "^\d{4}$"
Run Code Online (Sandbox Code Playgroud)
perl -Mre=debug -e'/^\d\d\d\d$/'
Run Code Online (Sandbox Code Playgroud)
Compiling REx "^\d\d\d\d$"
Final program:
1: BOL (2)
2: DIGIT (3)
3: DIGIT (4)
4: DIGIT (5)
5: DIGIT (6)
6: EOL (7)
7: END (0)
anchored ""$ at 4 stclass DIGIT anchored(BOL) minlen 4
Freeing REx: "^\d\d\d\d$"
Run Code Online (Sandbox Code Playgroud)
现在我要看看每个版本的表现如何.
#! /usr/bin/env perl
use Benchmark qw':all';
cmpthese( -10, {
'loop' => sub{ 1234 =~ /^\d{4}$/ },
'repeat' => sub{ 1234 =~ /^\d\d\d\d$/ }
});
Run Code Online (Sandbox Code Playgroud)
Rate loop repeat
loop 890004/s -- -10%
repeat 983825/s 11% --
虽然/^\d\d\d\d$/确实一直运行得更快,但速度并不快.这真的只是让它失去可读性.
让我们把这个例子推向极致:
/^\d{32}$/;
/^\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d$/;
Run Code Online (Sandbox Code Playgroud)
我不认为有很多人会认为第二个例子更容易阅读.
如果我们把它带到另一个极端,第一种风格似乎是彻头彻尾的多余.
/^\d{1}$/;
/^\d$/;
Run Code Online (Sandbox Code Playgroud)
所以真正归结为,\d在您的偏好从重复之后切换\d到使用量词之前,重复多少次.
任何超过3或4的重复都难以一目了然.我认为这是一个令人信服的理由.最重要的是,使用量词是表达重复信息的"密集"方式.对我来说,这就像复制和粘贴代码"重用"与编写真正可重用代码之间的区别.