下面的测试程序说明了我在尝试区分MessageID和电子邮件地址时遇到的一个问题,特别是当我事先不知道我正在解析电子邮件标题时。
#!/opt/perl/bin/perl
# use Regexp::Debugger;
use warnings;
no warnings qw(experimental::vlb);
my $re = qr{
(
(?:
# one or more of these
[\=a-z0-9!\#$%&'*+/?^_`{|}~-]+
# zero or more of these
(?:\.[\=a-z0-9!\#$%&'*+/?^_`{|}~-]+)*
)
@
(?:
(?!\d+\.\d+)
(?=.{4,255})
(?:
(?:[a-zA-Z0-9-]{1,63}(?<!-)\.)+
[a-zA-Z0-9-]{2,63}
)
)
)
}xims;
my $text = <<'EOF';
Arbitrary text followed by a snippet of an email header:
To: "T B" <[email protected]>, "Foobar" <[email protected]>
Message-ID: <[email protected]>
More text.
EOF
while ( $text =~ m/$re/g ) {
print "$1\n";
}
字符串
输出量:
[email protected]
[email protected]
[email protected]
型
我想要的输出是
[email protected]
[email protected]
型
我试着在(?<=To:\ )
后面添加一个外观,但没有匹配。
更大的程序对输入文本应用了几百个正则表达式。每个正则表达式都是一个特定的类型,例如foo => qr/[Ff]oo/,如果匹配,则该文本会被一个标记“ Package ”,以标识它匹配的正则表达式。例如foo。
2条答案
按热度按时间jchrr9hc1#
随着问题的澄清(以及不只是请求正则表达式的变化),这里有一个关于它的看法。
首先提取所有的标题,每个标题都有下一个标题的文本(因为我们不知道如果它嵌入在文本中,标题在哪里停止)。然后我们可以从每个这样的项目中提取地址,并且只从我们想要的标题中提取。必须首先获得 * 所有 * 标题,否则不需要的标题将被我们匹配的标题所吸收。
字符串
请注意,我在问题的文本中添加了一些标题,一个多行。
这是相当基本的,我相信有一些情况下没有得到正确的捕捉;解析电子邮件标题是棘手的。但希望它适用于问题中所示的简化情况。
也可以过滤掉不需要的标题了
型
然后你可以扔在一个
map
和获取地址的权利,以及那里,但我不认为有理由塞它这样。文本中的正则表达式允许标题在一行中的任何位置开始。但是如果它们总是在一行的开头开始,那么这可能是一个很好的限制。那么我们将有
型
现在我们需要'multiline'修饰符(
/m
),这样^
就可以匹配文本中的新行。然后整个字符串的结尾就是\Z
(因为$
现在匹配文本中每一行的结尾)。fv2wmkja2#
尝试以下 * 捕获模式 *。
字符串
或者,匹配模式。
型