我的perl正则表达式有什么问题

时间:2014-07-04 22:01:31

标签: regex perl shell unix

我试图在文本文件中找到不良记录:

文件中数据的格式为:

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错误吗?

2 个答案:

答案 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