正则表达式性能:验证字母数字字符

5

当尝试验证一个字符串只由字母字符组成时,我想到了两种可能的正则表达式解决方案。

第一种方法检查字符串中的每个字符是否是字母数字字符:

/^[a-z]+$/

第二种方法是在字符串中查找一个字母数字字符:
/[^a-z]/

(是的,我可以在这里使用字符类。)

对于长字符串,是否有显着的性能差异? (如果有,我猜第二种变体会更快。)


为什么不测试一下呢?创建一些大型数据集(或从其他地方导入),构建脚本,进行100次迭代或类似的时间测试。 - Alex Brown
3
为什么第一个正则表达式需要捕获? - Joseph Silber
嗯,好问题。我复制粘贴了捕获组,这是不必要的。 - Franz
2个回答

4
看起来第二种方法更快,但我做了一个快速的非科学测试,结果似乎不确定:正则匹配 vs. 否定
附注:我从第一种方法中移除了组捕获。它是多余的,只会减慢速度。

嘿,为什么测试字符串中要加';'字符?我们不需要有效的输入吗? - Maarten Bodewes
@owlstead - 正确。我为两种情况(通过/失败)添加了测试,结果似乎因浏览器而异。 - Joseph Silber
1
顺便问一句,有人能解释一下Opera使用了什么巫术才能得到这样的结果吗? - Joseph Silber
感谢测试。抱歉关于组捕获那是我的错误。 - Franz
在我的看法中,对于传递的情况似乎并没有太大的区别。在这种情况下,我会选择匹配所有字符的正则表达式,因为它更清晰。另一个需要双重否定才能得到积极结果。 - Maarten Bodewes
话虽如此,您可以使用另一个来检索第一个不匹配的字符,这可以用于创建更好的错误条件(具有值为$c的字符#i不是字母数字)。嗯,无论哪个是你的菜,我猜 :) - Maarten Bodewes

2

我写了这个快速Perl代码:

    @testStrings = qw(asdfasdf asdf as aa asdf as8up98;n;kjh8y  puh89uasdf ;lkjoij44lj 'aks;nasf na ;aoij08u4 43[40tj340ij3 ;salkjaf;  a;lkjaf0d8fua ;alsf;alkj   
a a;lkf;alkfa as;ldnfa;ofn08h[ijo ok;ln n ;lasdfa9j34otj3;oijt 04j3ojr3;o4j ;oijr;o3n4f;o23n a;jfo;ie;o ;oaijfoia ;aosijf;oaij ;oijf;oiwj; 
qoeij;qwj;ofqjf08jf0 ;jfqo;j;3oj4;oijt3ojtq;o4ijq;onnq;ou4f ;ojfoqn;aonfaoneo ;oef;oiaj;j a;oefij iiiii iiiiiiiii iiiiiiiiiii); 


    print "test 1: \n";
    foreach my $i (1..1000000) {
            foreach (@testStrings) {
                    if ($_ =~ /^([a-z])+$/) {
                            #print "match"
                    } else {
                            #print "not"
                    }
            }
    }

    print `date` . "\n";

    print "test 2: \n";
    foreach my $j (1..1000000) {
            foreach (@testStrings) {
                    if ($_ =~ /[^a-z]/) {
                            #print "match"
                    } else {
                            #print "not"
                    }
            }
    }

然后使用以下命令运行: date; <perl_file>; date

这并不是百分之百科学的,但它给了我们一个很好的想法。第一个正则表达式执行了10或11秒钟,第二个正则表达式执行了8秒钟。


你应该从第一个正则表达式中删除组捕获。 - Joseph Silber
我注意到了,但最初没有删除它,所以我按照要求完全运行了正则表达式。然而,我继续删除它,并且在时间上没有任何区别(我进行了约10次测试)。 - pirhac
你应该将通过/失败的实例分别记录。它们是非常不同的。 - Joseph Silber
感谢您的测试。对于群组捕获,我很抱歉,那是我的错误。 - Franz
通常情况下,组捕获并没有太大的区别;它相当于将索引存储到字符串中(至少如果字符串本身是可变的,就像在Java中一样)。即使您检索匹配的组,它仍然可能指向相同的内存位置(再次,如果这个过程与Java中的反应一样)。 - Maarten Bodewes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接