\Q 和 \E 中的哈希
Hash inside \Q and \E
我想将包含散列(或井号字符“#”)的模式与 perl 匹配:
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
if( $#ARGV + 1 != 2 ) {
die "ERROR: Number of command line arguments is not 2";
}
my $input = $ARGV[ 0 ];
my $output = $ARGV[ 1 ];
open( my $ifh, "<:encoding(UTF-8):crlf", "$input" )
|| die "ERROR: Failed to open input file: $!";
my $content = do { local $/; <$ifh> };
open( my $ofh, ">:encoding(UTF-8):crlf", "$output" )
|| die "ERROR: Failed to open output file: $!";
eval { # GLOBAL EXCEPTION HANDLER BEGIN
{ ( ( my $fix, my $dat, my $rest ) = ( $content
=~ / ^ ( \Q# started on \E ) ([^\n]+) \n{3}
(.*)
$ /xs
) ) || die "ERROR: No match";
print $ofh __LINE__ . "\tDate\t$dat\n";
$content = $rest; }
}; if( $@ ) { print $ofh "$@____________\n"; print $ofh "$content"; } # GLOBAL EXCEPTION HANDLER END
这给出了以下错误消息:
Unmatched ( in regex; marked by <-- HERE in m/ ^ ( <-- HERE \#\ started\ on\ \E\ \)\ \(\[\^\n\]\+\)\ \n\{3\}\
\ \ \ \ \ \ \ \(\.\*\)\
\ \ \ \ \ $\ / at ./example.pl line 25.
但是,如果我这样修改它,那么它就完美了:
{ ( ( my $fix, my $dat, my $rest ) = ( $content
=~ / ^ ( \# \Q started on \E ) ([^\n]+) \n{3}
(.*)
$ /xs
) ) || die "ERROR: No match";
print $ofh __LINE__ . "\tDate\t$dat\n";
$content = $rest; }
不过,我更愿意将主题标签保留在 \Q
和 \E
块中。
那么问题来了,\Q
和\E
是不是把里面的东西都转义了?或者这里有什么问题?
#
在带有 /x
的正则表达式中引入注释。即使在 /x
.
下的 \Q...\E
中,您也需要反斜杠
顺便说一句,通过使用 or
而不是 ||
进行流量控制,可以使 eval
内的部分更具可读性(无论如何,这是推荐的做法)。另外,不要在错误后继续设置 $@
,旧的 Perl 版本中存在错误导致无法正确设置。相反,return 来自 eval
的真实值并检查它,例如
{
( my $fix, my $dat, my $rest )
= $content =~ / ^ ( \Q \# started on \E ) ([^\n]+) \n{3}
(.*)
$
/xs or die "ERROR: No match";
1 } or do { # Handle the exception...
更新: 这是 Perl 中的一个错误。请注意,它仅在字面上使用 octothorpe 时才会命中,即您可以将其存储在变量中并且它会起作用:
my $octothorpe = '#';
print 'a # b' =~ /(\Q $octothorpe \E) b/x
我想将包含散列(或井号字符“#”)的模式与 perl 匹配:
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
if( $#ARGV + 1 != 2 ) {
die "ERROR: Number of command line arguments is not 2";
}
my $input = $ARGV[ 0 ];
my $output = $ARGV[ 1 ];
open( my $ifh, "<:encoding(UTF-8):crlf", "$input" )
|| die "ERROR: Failed to open input file: $!";
my $content = do { local $/; <$ifh> };
open( my $ofh, ">:encoding(UTF-8):crlf", "$output" )
|| die "ERROR: Failed to open output file: $!";
eval { # GLOBAL EXCEPTION HANDLER BEGIN
{ ( ( my $fix, my $dat, my $rest ) = ( $content
=~ / ^ ( \Q# started on \E ) ([^\n]+) \n{3}
(.*)
$ /xs
) ) || die "ERROR: No match";
print $ofh __LINE__ . "\tDate\t$dat\n";
$content = $rest; }
}; if( $@ ) { print $ofh "$@____________\n"; print $ofh "$content"; } # GLOBAL EXCEPTION HANDLER END
这给出了以下错误消息:
Unmatched ( in regex; marked by <-- HERE in m/ ^ ( <-- HERE \#\ started\ on\ \E\ \)\ \(\[\^\n\]\+\)\ \n\{3\}\
\ \ \ \ \ \ \ \(\.\*\)\
\ \ \ \ \ $\ / at ./example.pl line 25.
但是,如果我这样修改它,那么它就完美了:
{ ( ( my $fix, my $dat, my $rest ) = ( $content
=~ / ^ ( \# \Q started on \E ) ([^\n]+) \n{3}
(.*)
$ /xs
) ) || die "ERROR: No match";
print $ofh __LINE__ . "\tDate\t$dat\n";
$content = $rest; }
不过,我更愿意将主题标签保留在 \Q
和 \E
块中。
那么问题来了,\Q
和\E
是不是把里面的东西都转义了?或者这里有什么问题?
#
在带有 /x
的正则表达式中引入注释。即使在 /x
.
\Q...\E
中,您也需要反斜杠
顺便说一句,通过使用 or
而不是 ||
进行流量控制,可以使 eval
内的部分更具可读性(无论如何,这是推荐的做法)。另外,不要在错误后继续设置 $@
,旧的 Perl 版本中存在错误导致无法正确设置。相反,return 来自 eval
的真实值并检查它,例如
{
( my $fix, my $dat, my $rest )
= $content =~ / ^ ( \Q \# started on \E ) ([^\n]+) \n{3}
(.*)
$
/xs or die "ERROR: No match";
1 } or do { # Handle the exception...
更新: 这是 Perl 中的一个错误。请注意,它仅在字面上使用 octothorpe 时才会命中,即您可以将其存储在变量中并且它会起作用:
my $octothorpe = '#';
print 'a # b' =~ /(\Q $octothorpe \E) b/x