我正在修改旧的邮件工具并添加MIME支持。我有很多工作,但我是一个perl假人和正则表达式的东西正在失去我。
我有:
foreach ( @{$body} ) {
next if /^$/;
if ( /NEMS/i ) {
/.*?(\d{5,7}).*/;
$nems = $1;
next;
}
if ( $delimit ) {
next if (/$delimit/ && ! $tp);
last if (/$delimit/ && $tp);
$tp = 1, next if /text.plain/;
$tp = 0, next if /text.html/;
s/<[^>]*>//g;
$newbody .= $_ if $tp;
} else {
s/<[^>]*>//g;
$newbody .= $_ ;
}
} # End Foreach
现在我感谢MIME::Parser $body_text
作为纯文本邮件正文。所以现在我只需要这个部分就可以了:
foreach ( @{$body_text} ) {
next if /^$/;
if ( /NEMS/i ) {
/.*?(\d{5,7}).*/;
$nems = $1;
next;
}
} # End Foreach
实际的挑战是找到NEMS=12345
或NEMS=1234567
并设置$nems=12345
(如果找到)。我认为我的测试有一个非常基本的语法问题,因为我没有经常暴露于perl。
一位同事建议:
foreach (split(/\n/,$body_text)){
next if /^$/;
if ( /NEMS/i ) {
/.*?(\d{5,7}).*/;
$nems = $1;
next;
}
}
这似乎有效,但它可能不是首选方式?
编辑:
所以这是基于此处提示和测试的最新版本:
foreach (split(/\n/,$body_text)){
next if /^$/;
if ( /NEMS/i ) {
/^\s*NEMS\s*=\s*(\d+)/i;
$nems = $1;
next;
}
}
答案 0 :(得分:-1)
将最后两位数字匹配为可选项并捕获前五位数字,并直接指定捕获
($nems) = /.*? (\d{5}) (?: \d{2} )?/x; # /x allows spaces inside
构造(?: )
仅对内部的内容进行分组,而不进行捕获。 ?
之后的意思是匹配零次或一次。我们需要parens,以便它仅适用于该子模式。所以最后两位数字是可选的 - 五位数或七位数匹配。我还在最后删除了不需要的.*
。
然而,按照你所说的,似乎整个事情可以简化
if ( ($nems) = /^\s*NEMS \s* = \s* (\d{5}) (?:\d{2})?/ix ) { next }
现在不需要if (/NEMS/)
,我已经调整了NEMS
在开头的澄清,并且=
周围可能有空格。然后你也可以说
my $nems;
foreach ( split /\n/, $body_text ) {
# ...
next if ($nems) = /^\s*NEMS\s*=\s*(\d{5})(?:\d{2})?/i;
# ...
}
包括澄清新$body_text
是多行字符串的内容。
很明显,$nems
被声明(需要)在之外的循环,我指出了。
这允许更多数字跟随;它也将匹配8位数字(但只捕获前5位)。这就是正则表达式中的尾随.*
所暗示的内容。
编辑已经澄清,只能有5位或7位数字。然后可以收紧正则表达式,以检查输入是否符合预期,但它也应该按原样运行。
一些注意事项,如果有更多信息可以告诉我
匹配运算符返回一个列表,因此我们需要 ($nems) = /.../;
中的parens
对于($nems) = /.../
,($nems) = $_ =~ /.../;
语法是一个不错的快捷方式
如果你匹配$_
以外的变量,那么你需要完整的东西。
总是希望用
启动Perl程序use warnings 'all';
use strict;
这直接有助于并且通常会产生更好的代码。
对演化问题理解的澄清说明=
之后的所有数字都需要被捕获到$nems
(并且可能有5个,(不是6个),7,8,9,10个数字) 。那么正则表达式就是
($nems) = /^\s*NEMS\s*=\s*(\d+)/i;
其中\d+
表示一位数,一次或多次。所以是一串数字(如果没有则匹配失败)。