我试图在文本文件中找到不良记录:
文件中数据的格式为:
somedata\x1Fsomemoredata\x1F\n
somedata2\x1Fsomemoredata2\x1F\n
(\ x1F是以十六进制值表示的单位分隔符,此数据使用Perl的chr(31)在另一个脚本中写出,这是单位分隔符的ascii代码)
我写的是perl:
## the format of each record in the file: alphanumericdata\x1Falphanumericdata\x1F\n
my $regex = "/[A-z0-9]+\\x1F[A-z0-9]+\\x1F\\n\$/";
print $regex;
#### just opening file
my $filename = "data.txt";
open(my $fh, "<:encoding(UTF-8)", $filename)
or die "Could not open file '$filename' $!";
### reading file line by line
while (my $row = <$fh>) {
## if line does not match format, print the culprit!!!
if($row !~ $regex) {
print $row;
}
}
close $fh;
这会打印每一行,但我知道大多数行的格式都是正确的,因此我的正则表达式已经关闭了。
我在这里犯了一些noob错误吗?
答案 0 :(得分:2)
你想要的是qr()
,这是存储正则表达式的正确方法:
my $regex = qr([A-z0-9]+\x1F[A-z0-9]+\x1F\n$);
答案 1 :(得分:2)
问题是您在模式中包含了Perl匹配运算符(Perl代码)。
my $pat = "^[A-z0-9]+\\x1F[A-z0-9]+\\x1F\\n\\z";
if ($row !~ m/$pat/)
if ($row !~ /$pat/) # shortcut
if ($row !~ $pat) # shortcut
将模式硬编码为字符串文字是没有意义的,所以让我们假装从文件中读取$pat
。在这种情况下,您需要预编译它。
# Pretend we're reading ^[A-z0-9]+\x1F[A-z0-9]+\x1F\n\z from a file.
my $pat = "^[A-z0-9]+\\x1F[A-z0-9]+\\x1F\\n\\z";
my $re = qr/$pat/;
if ($row !~ m/$re/)
if ($row !~ /$re/) # shortcut
if ($row !~ $re) # shortcut
如果您对文件进行了硬编码,则可以直接使用qr//
。它可以避免你逃避一堆斜线。
my $re = qr/^[A-z0-9]+\x1F[A-z0-9]+\x1F\n\z/;
if ($row !~ m/$re/)
if ($row !~ /$re/) # shortcut
if ($row !~ $re) # shortcut
在这种情况下,似乎没有理由预先指定模式。您可以在匹配运算符中指定。
if ($row !~ m/^[A-z0-9]+\x1F[A-z0-9]+\x1F\n\z/)
if ($row !~ /^[A-z0-9]+\x1F[A-z0-9]+\x1F\n\z/) # same