在模式之前找到两个字母字符[a-zA-Z],排除其间的所有非字符

时间:2014-06-23 06:20:23

标签: regex perl

我需要在字符串中的五位数之前找到两个字母字符。

示例 -

Revert changes made on _AB : 12342  
AB12342 reverted the changes
Revert the changes onab :_ 12342 id

在上述所有情况下,我需要输出为AB12342

我尝试了以下正则表达式

if ($msg =~ /([a-zA-Z]{2})(\d{5})/)

if ($msg =~ /([a-zA-Z]{2})(.*)?(\d{5})/)

if ($msg =~ /([a-zA-Z]{2})(.*)?(\d{5})/)

在第一种情况下,它在比赛前只考虑了2个连续的字符。所以我尝试使用.*模式,它给了我整个字符串的前两个字符。所以我尝试使用贪婪的运算符,如第三行,但它仍然无法正常工作。我不知道哪里出错了。

4 个答案:

答案 0 :(得分:1)

如果不转换为大写,请使用:

$subject =~ s/([a-z]{2})[^\da-z]+(\d{5})/$1$2/ig;
  • i标志使正则表达式不区分大小写
  • ([a-z]{2})会抓取两封信给第1组
  • [^\da-z]+匹配任意数量的既不是字母也不是数字的字符
  • (\d{5})将五位数字捕获到第二组
  • $1$2将其替换为第1组+第2组(删除其中的所有内容)

要转换为大写,我们需要在lambda中使用uc()。请参阅online demo底部的输出。

$regex = '(?i)([a-z]{2})[^\da-z]+(\d{5})';
$subject = ' _AB : 12342  onab :_ 12342 ';
($replaced = $subject) =~ s/$regex/
         { uc($1) . $2; }  /eg;
print $replaced . "\n";

删除前缀

请注意,字符串已正确替换,但变量的前缀为_AB12342onAB12342。我很乐意删除任何前缀,例如任何非空格字符,如果您认为它是安全的。

答案 1 :(得分:0)

以下正则表达式将捕获五位数前面的最后两个字母。

.*([A-Za-z]{2}).*?(\d{5}).*

DEMO

答案 2 :(得分:0)

我认为您需要将(.*)?更改为[^a-zA-Z]*以排除所有非字字符。

$msg =~ /([a-zA-Z]{2})[^a-zA-Z]*\d{5}/

答案 3 :(得分:0)

此代码:

while (my $msg = <DATA>) { chomp $msg;
    if ($msg =~ /([a-zA-Z]{2})\s*:?\s*_?\s*(\d{5})/) {
        printf("%s: %s%d\n", $msg, uc $1, $2);
    }   
}

__DATA__
Revert changes made on _AB : 12342
AB12342 reverted the changes
Revert the changes onab :_ 12342 id

给出:

Revert changes made on _AB : 12342: AB12342
AB12342 reverted the changes: AB12342
Revert the changes onab :_ 12342 id: AB12342