如何在某个字符前限制匹配长度?

时间:2013-04-21 21:03:21

标签: regex perl

我使用以下正则表达式扫描输入文本文件以获取有效的电子邮件。

[A-Za-z0-9!#$%&*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?

现在我还需要在' @'之前将匹配限制为20个字符。登录电子邮件地址,但不知道如何操作。

PS。我正在使用Delphi XE2中的Perl正则表达式库(TPerlRegex)。

你能帮助我吗?

2 个答案:

答案 0 :(得分:5)

由于您的库应该与PERL兼容,因此它应该支持lookaheads。这些方便了以确保模式中的几个“正交”限制:

(?=[^@]{1,20}@)[A-Za-z0-9!#$%&*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?

只有在不超过20个非@个字符后有@时,才会匹配前瞻。但是,前瞻实际上并没有提升正则表达式引擎在主题字符串中的位置,因此在检查条件后,引擎仍处于电子邮件的开头(或者当前正在检查的任何位置)并且像以前一样继续你的模式。

答案 1 :(得分:2)

考虑使用Email::Address来捕获电子邮件地址,然后grep ping那些在@之前有20个或更少字符的人的结果:

use strict;
use warnings;
use Email::Address;

my @addresses;

while ( my $line = <DATA> ) {
    push @addresses, $_
      for grep { /([^@]+)/ and length $1 < 21 }
      Email::Address->parse($line);
}

print "$_\n" for @addresses;

__DATA__
ABCDEFGHIJKLMNOPQRSTUVWXYZguest@host.com frank@email.net Line noise. test@host.com
Some stuff here... help@perl.org And even more here!
Nothing to see here.  01234567890123456789@numbers.com  Nothing to see.

输出:

frank@email.net
test@host.com
help@perl.org
01234567890123456789@numbers.com