n个字符或至少m个字符的正则表达式

时间:2011-12-22 19:24:21

标签: regex character

这应该是一个非常简单的正则表达式问题,但我无法在任何地方找到任何答案。如何制作一个正则表达式,它只匹配2个字符或至少4个字符。这是我目前的做法(忽略正则表达式本身,除此之外):

[A-Za-z0_9_]{2}|[A-Za-z0_9_]{4,}

但是,这个方法花费了两倍的时间(对于400行文件,我的速度大约慢了0.3秒),所以我想知道是否有更好的方法可以做到这一点?

4 个答案:

答案 0 :(得分:16)

优化开头,然后锚定它。

^[A-Za-z0-9_]{2}(?:|[A-Za-z0-9_]{2,})$

(另外,你确实说要忽略正则表达式本身,但我猜你可能想要0-9,而不是0_9

编辑嗯,我确信我读到你要匹配。如果您想在线内匹配,请移除锚点(^$)。如果你只匹配整行,锚点会加快你的速度(好吧,前锚^至少会。)

答案 1 :(得分:3)

你的解决方案看起来很不错。作为替代方案,您可以尝试像这样的人:

[A-Za-z0-9_]{2}(?:[A-Za-z0-9_]{2,})?

顺便说一下,我想你想要连字符而不是09之间的下划线,不是吗?

答案 2 :(得分:1)

您提出的解决方案是正确的。

如果您正在尝试优化例程,并且匹配2个或更多字符的匹配字符串数远小于不匹配的字符串数,请考虑接受长度为2或更大的所有字符串,然后抛出这些字符串,如果它们是长度为3.这可以通过仅检查一次正则表达式来提高性能,而第二次调用甚至不需要是正则表达式;检查字符串长度通常是一个非常快的操作。

与往常一样,您确实需要对真实数据运行测试,以验证这是否会提高您的速度。

答案 3 :(得分:-1)

所以基本上你想匹配长度为2或2 + 2 + N,N> = 0的单词

([A-Za-z0-9][A-Za-z0-9](?:[A-Za-z0-9][A0Za-z0-9])*)

工作示例:

#!/usr/bin/perl

while (<STDIN>)
{
    chomp;
    my @matches = ($_=~/([A-Za-z0-9][A-Za-z0-9](?:[A-Za-z0-9][A0Za-z0-9])*)/g);
    for my $m (@matches) {
        print "match: $m\n";
    }
}

输入文件:

cat in.txt
ab abc bcad a as asdfa
aboioioi i i abc bcad a as asdfa

输出:

perl t.pl <in.txt
match: ab
match: ab
match: bcad
match: as
match: asdf
match: aboioioi
match: ab
match: bcad
match: as
match: asdf