这应该是一个非常简单的正则表达式问题,但我无法在任何地方找到任何答案。如何制作一个正则表达式,它只匹配2个字符或至少4个字符。这是我目前的做法(忽略正则表达式本身,除此之外):
[A-Za-z0_9_]{2}|[A-Za-z0_9_]{4,}
但是,这个方法花费了两倍的时间(对于400行文件,我的速度大约慢了0.3秒),所以我想知道是否有更好的方法可以做到这一点?
答案 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,})?
顺便说一下,我想你想要连字符而不是0
和9
之间的下划线,不是吗?
答案 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