如何重新定义\ s以匹配下划线?

时间:2015-07-13 23:56:56

标签: regex perl character-class

用于空格的Perl(< v5.18)正则表达式字符类\s[\t\n\f\r ]相同。

现在,由于某些文件名使用下划线作为空格,我想知道是否可以重新定义\s(本地)以匹配除空格之外的下划线。

这仅仅是为了具有许多[\s_]的其他复杂正则表达式的可读性。我可以这样做吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:12)

每当我认为Perl中的某些东西是不可能的时,通常会发现我错了。有时当我认为Perl中的某些内容非常困难时,我也错了。 @sln把我指向了right track

尽管你可以,但我们还是暂不覆盖\s。为了让你的程序的继承人期望\s表示特定的东西,而是让我们将序列\_定义为正则表达式中的“任何空格字符或_字符” 。详细信息在上面的链接中,但实现如下:

package myspace;  # redefine  \_  to mean  [\s_]
use overload;
my %rules = ('\\' => '\\\\', '_' => qr/[\t\n\x{0B}\f\r _]/ );
sub import {
    die if @_ > 1;
    overload::constant 'qr' => sub {
        my $re = shift;
        $re =~ s{\\(\\|_)}{$rules{$1}}gse;
        return $re;
    };
}
1;

现在在你的脚本中,说

use myspace;

现在正则表达式\_表示[\s_]

演示:

use myspace;
while (<DATA>) {
    chomp;
    if ($_ =~ /aaa\s.*txt/) {      # match whitespace
        print "match[1]: $_\n";
    }
    if ($_ =~ /aaa\_.*txt/) {      # match [\s_]
        print "match[2]: $_\n";
    }
    if ($_ =~ /\\_/) {             # match literal  '\_'
        print "match[3]: $_\n";
    }
}
__DATA__
aaabbb.txt
aaa\_ccc.txt
cccaaa bbb.txt
aaa_bbb.txt

输出:

match[3]: aaa\_ccc.txt
match[1]: cccaaa bbb.txt
match[2]: cccaaa bbb.txt
match[2]: aaa_bbb.txt

第三种情况是证明正则表达式中的\\_与文字\_匹配,如\\s将与文字\s匹配。