Как переопределить, чтобы соответствовать подчеркиваниям?

Perl (\s для пробелов так же, как [\t\n\f\r ],

Теперь, так как некоторые имена файлов используют подчеркивание в качестве пробелов, мне было интересно, можно ли переопределить \s (локально), чтобы соответствовать подчеркиваниям в дополнение к пробелам.

Это было бы просто ради удобочитаемости извилистых регулярных выражений, имеющих много [\s_], Я могу это сделать? Если так, то как?

1 ответ

Решение

Всякий раз, когда я думаю, что в Perl что-то невозможно, обычно оказывается, что я неправ. И иногда, когда я думаю, что что-то очень сложно в Perl, я тоже ошибаюсь. @sln указал мне правильный путь

Не будем переопределять \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,

Другие вопросы по тегам