【问题标题】:What is wrong with my perl regex我的 perl 正则表达式有什么问题
【发布时间】:2014-08-26 04:43:52
【问题描述】:

我正在尝试在文本文件中查找不良记录:

文件中数据的格式为:

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;

这会打印每一行,但我知道大多数行的格式都正确,所以我的正则表达式有些问题。

我在这里犯了一些菜鸟错误吗??

【问题讨论】:

  • 您的文本中是否真的有字符 \x1F(4 个字符),或者这只是一个单个字节的转义表示十六进制代码(例如 0x1F = 十进制 37)?
  • 您是否通过尝试将正则表达式存储为双引号字符串而使事情变得不必要地困难?使用qr()——这就是它的用途。
  • 文本没有文字字符 \,x,1,F.. 这只是来自 ASCII table@MarcB 的 UNIT 分隔符的表示

标签: regex perl shell unix


【解决方案1】:

问题是您在模式中包含了 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

在这种情况下,似乎没有理由提前指定模式。您可以在匹配运算符中指定 right。

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

【讨论】:

    【解决方案2】:

    你想要的是qr(),这是存储正则表达式的正确方法:

    my $regex = qr([A-z0-9]+\x1F[A-z0-9]+\x1F\n$);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 2012-02-24
      • 2013-04-11
      相关资源
      最近更新 更多