4

任何人都可以帮我解决这个正则表达式吗?我需要一个表达式来匹配最后不包含“Created”字符串的行。该脚本用于阅读某些源代码的标题。

$string = "* JAN-01-2001   bugsbunny     1234     Created Module";
#$string = "* DEC-12-2012   bugsbunny     5678     Modified Module";
if($string =~ /^\*\s+(\w\w\w-\d\d-\d\d\d\d)\s+(\w+)\s+(\d+)\s+(?!Created)/){
    print "$1\n$2\n$3\n$4\n";
} else {
    print "no match\n";
}

使用第一个 $string 定义时,我需要匹配失败,因为它的末尾有单词“Created”。当使用第二个 $string 定义时,它应该通过,我需要提取日期($1)、用户($2)、更改编号($3)和描述($4)。

上面的表达式不起作用。请问有什么建议吗?

4

4 回答 4

4

Close:

/^\*\s+(\w{3}-\d{2}-\d{4})\s+(\w+)\s+(\d+)\s+(?!.*Created)/

You need to allow any number of non-newline characters before Created, therefore the .*.

Otherwise, the regex would simply back up by one character when matching \s+, so the following text would be " Created", and then (?!Created) would match.

See it here; notice how the match stops one space before Created.

于 2013-02-05T07:59:25.433 回答
1

您可以用来完成这项工作的另一个技巧是使用(?>...)禁用回溯的组。禁用回溯意味着任何使用+or的表达式*都会贪婪地吃掉它找到的任何东西,如果模式失败,它永远不会回去尝试其他东西。这意味着“创建”之前的所有空白都被吃掉了,所以(?!Created)正则表达式的部分总是出现在正确的位置。

if($string =~ /^(?>\*\s+(\w\w\w-\d\d-\d\d\d\d)\s+(\w+)\s+(\d+)\s+)(?!Created)/){
    print "$1\n$2\n$3\n";
} else {
    print "no match\n";
}

这还具有使您的正则表达式更快的额外好处。

这种方法不适用于所有类型的问题,因为许多正则表达式需要能够回溯才能正确匹配。但这对这个很有用。

于 2013-02-05T10:44:07.573 回答
0
$string = "* JAN-02-2001   bugsbunny     1234     Created Module";
$string = "* DEC-12-2012   bugsbunny     5678     Modified Module";
if($string =~ /^\*\s+(\w\w\w-\d\d-\d\d\d\d)\s+(\w+)\s+(\d+)\s+([^Created]|Modified)\s+(\w+)/){
    print "$1\n$2\n$3\n$4\n";
}
else {
    print "no match\n";
}
于 2014-12-16T06:51:06.707 回答
0

另一种选择是split测试“已创建”的描述:

use strict;
use warnings;

#my $string = "* JAN-01-2001   bugsbunny     1234     Created Module";
my $string = "* DEC-12-2012   bugsbunny     5678     Modified Module";

my ( undef, $date, $user, $change, $desc ) = split ' ', $string, 5;

if ( $desc !~ /^Created/ ) {
    print "$date\n$user\n$change\n$desc\n";
}
else {
    print "no match\n";
}

输出:

DEC-12-2012
bugsbunny
5678
Modified Module
于 2013-02-05T15:47:59.363 回答