为什么这个来自文本文件的正则表达式不能与 smartmatch 一起使用?
Why is this regex from a text file not working with smartmatch?
我用
smartmatch
检查字符串是否匹配正则表达式模式。在我决定将正则表达式存储在文本文件中后它停止工作。
my $str = '123456, some text.';
my $regex = qr/^\d+, some text\.$/;
print "Regex: $regex\n";
此时打印出的正则表达式为(?^:^\d+, some text\.$)
。我将它复制粘贴到一个文件中,然后让代码读取文件并检索存储在 $regexFromFile
.
中的正则表达式
以下行确认 $regex
和 $regexFromFile
相同,然后我继续以各种方式针对正则表达式测试 $str
。
print 'Is regex equal to regexFromFile? ' . ($regex eq $regexFromFile) . "\n";
print 'Does str match regex using =~ ? ' . ($str =~ $regex) . "\n";
print 'Does str match regexFromFile using =~ ? ' . ($str =~ $regexFromFile) . "\n";
print 'Does str match regex using ~~ ? ' . ($str ~~ $regex) . "\n";
print 'Does str match regexFromFile using ~~ ? ' . ($str ~~ $regexFromFile) . "\n";
该代码的最后一行与前三行的行为不同。
这里是代码的完整输出:
Regex: (?^:^\d+, some text\.$)
Is regex equal to regexFromFile? 1
Does str match regex using =~ ? 1
Does str match regexFromFile using =~ ? 1
Does str match regex using ~~ ? 1
Does str match regexFromFile using ~~ ?
(注意最后没有 1
。)
编辑:要回答评论,这里是读取文件的方式。
open(my $FILEHANDLE, 'file.txt') or die "Error: Could not open file.\n";
my @content = <$FILEHANDLE>;
close($FILEHANDLE) or print "Could not close file.\n";
my @content_woEol = ();
foreach my $line (@content){
$line =~ s/\s*$//;
push(@content_woEol, $line);
}
my $regexFromFile = $content_woEol[0];
Smartmatch 自 v5.18 以来一直是实验性的,不应该在实时制作软件中使用
一直需要
use feature 'switch';
除非您是有意或明确无视警告的人,否则
no warnings qw/ experimental::smartmatch /;
那么你就会收到它消亡的充分警告
你做出了一个从一开始就明显错误的明智选择
智能匹配已损坏。请避免使用。[1]
$str
是字符串,$regexFromFile
是字符串,所以$str ~~ $regexFromFile
等价于$str eq $regexFromFile
.
如果您希望 $str ~~ $regexFromFile
等同于 $str =~ $regexFromFile
,您必须将错误命名的 $regexFromFile
从字符串转换为正则表达式(例如使用 qr//
).当然,更好的解决方案是简单地使用 =~
.
- 很多年前,它作为一种弃用形式进行了实验,因此可以修复。继续使用这个损坏的功能实际上阻止了最近的修复工作。
qr//
的结果实际上是一个预编译的正则表达式。 Copy-pasting 将正则表达式打印到文件中,就像您所做的那样,然后从文件中读取它,这不是问题。如果您直接在代码中编写此行,您会遇到相同的行为:
my $regexFromFile = '(?^:^\d+, some text\.$)';
如果你想在这里使用 smatmatch,我建议你做如下的事情:
my $str = '123456, some text.';
my $regex = '^\d+, some text\.$';
# Manually store this in the file: ^\d+, some text\.$
# Read $regexFromFile from the file
print 'Does str match regex using =~ ? ' . ($str =~ /$regex/) . "\n";
print 'Does str match regexFromFile using =~ ? ' . ($str =~ /$regexFromFile/) . "\n";
print 'Does str match regex using ~~ ? ' . ($str ~~ /$regex/) . "\n";
print 'Does str match regexFromFile using ~~ ? ' . ($str ~~ /$regexFromFile/) . "\n";
注意额外的 /.../
。输出:
Does str match regex using =~ ? 1
Does str match regexFromFile using =~ ? 1
Does str match regex using ~~ ? 1
Does str match regexFromFile using ~~ ? 1
我用 smartmatch 检查字符串是否匹配正则表达式模式。在我决定将正则表达式存储在文本文件中后它停止工作。
my $str = '123456, some text.';
my $regex = qr/^\d+, some text\.$/;
print "Regex: $regex\n";
此时打印出的正则表达式为(?^:^\d+, some text\.$)
。我将它复制粘贴到一个文件中,然后让代码读取文件并检索存储在 $regexFromFile
.
以下行确认 $regex
和 $regexFromFile
相同,然后我继续以各种方式针对正则表达式测试 $str
。
print 'Is regex equal to regexFromFile? ' . ($regex eq $regexFromFile) . "\n";
print 'Does str match regex using =~ ? ' . ($str =~ $regex) . "\n";
print 'Does str match regexFromFile using =~ ? ' . ($str =~ $regexFromFile) . "\n";
print 'Does str match regex using ~~ ? ' . ($str ~~ $regex) . "\n";
print 'Does str match regexFromFile using ~~ ? ' . ($str ~~ $regexFromFile) . "\n";
该代码的最后一行与前三行的行为不同。
这里是代码的完整输出:
Regex: (?^:^\d+, some text\.$)
Is regex equal to regexFromFile? 1
Does str match regex using =~ ? 1
Does str match regexFromFile using =~ ? 1
Does str match regex using ~~ ? 1
Does str match regexFromFile using ~~ ?
(注意最后没有 1
。)
编辑:要回答评论,这里是读取文件的方式。
open(my $FILEHANDLE, 'file.txt') or die "Error: Could not open file.\n";
my @content = <$FILEHANDLE>;
close($FILEHANDLE) or print "Could not close file.\n";
my @content_woEol = ();
foreach my $line (@content){
$line =~ s/\s*$//;
push(@content_woEol, $line);
}
my $regexFromFile = $content_woEol[0];
Smartmatch 自 v5.18 以来一直是实验性的,不应该在实时制作软件中使用
一直需要
use feature 'switch';
除非您是有意或明确无视警告的人,否则
no warnings qw/ experimental::smartmatch /;
那么你就会收到它消亡的充分警告
你做出了一个从一开始就明显错误的明智选择
智能匹配已损坏。请避免使用。[1]
$str
是字符串,$regexFromFile
是字符串,所以$str ~~ $regexFromFile
等价于$str eq $regexFromFile
.
如果您希望 $str ~~ $regexFromFile
等同于 $str =~ $regexFromFile
,您必须将错误命名的 $regexFromFile
从字符串转换为正则表达式(例如使用 qr//
).当然,更好的解决方案是简单地使用 =~
.
- 很多年前,它作为一种弃用形式进行了实验,因此可以修复。继续使用这个损坏的功能实际上阻止了最近的修复工作。
qr//
的结果实际上是一个预编译的正则表达式。 Copy-pasting 将正则表达式打印到文件中,就像您所做的那样,然后从文件中读取它,这不是问题。如果您直接在代码中编写此行,您会遇到相同的行为:
my $regexFromFile = '(?^:^\d+, some text\.$)';
如果你想在这里使用 smatmatch,我建议你做如下的事情:
my $str = '123456, some text.';
my $regex = '^\d+, some text\.$';
# Manually store this in the file: ^\d+, some text\.$
# Read $regexFromFile from the file
print 'Does str match regex using =~ ? ' . ($str =~ /$regex/) . "\n";
print 'Does str match regexFromFile using =~ ? ' . ($str =~ /$regexFromFile/) . "\n";
print 'Does str match regex using ~~ ? ' . ($str ~~ /$regex/) . "\n";
print 'Does str match regexFromFile using ~~ ? ' . ($str ~~ /$regexFromFile/) . "\n";
注意额外的 /.../
。输出:
Does str match regex using =~ ? 1
Does str match regexFromFile using =~ ? 1
Does str match regex using ~~ ? 1
Does str match regexFromFile using ~~ ? 1