【问题标题】:Perl, regex, extract data from a linePerl,正则表达式,从一行中提取数据
【发布时间】:2010-04-09 16:13:20
【问题描述】:

我试图用 perl 提取一行的一部分

use strict; 
use warnings;


# Set path for my.txt and extract datadir
my @myfile = "C:\backups\MySQL\my.txt";
my @datadir = "";

open READMYFILE, @myfile or die "Error, my.txt not found.\n";
    while (<READMYFILE>) {
        # Read file and extract DataDir path
        if (/C:\backups/gi) {
        push @datadir, $_;
        }
    }

# ensure the path was found
print @datadir . " \n";

首先我试图设置 my.txt 文件的位置。接下来我试图阅读它并用正则表达式拉出部分行。我得到的错误是:

通过了无法识别的转义\m 在 1130.pl 第 17 行。

我查看了How can I grab multiple lines after a matching line in Perl? 以了解如何读取文件并匹配其中的一行,但我不能 100% 确定我这样做是正确的还是以最好的方式。我似乎也产生了错误:

错误,找不到 my.txt。

但该文件确实存在于文件夹 C:\backups\MySQL\

【问题讨论】:

  • Unrecognized escape \m 在 1130.pl 第 17 行通过。感谢 Mark Rushakoff 和 user275455 的解决方案,我只需要帮助解决 my.txt 文件未在在这一点上,感谢您说明了不止一种方法。
  • 到目前为止,我已经回答了几乎所有我需要的问题,我能够修复前面提到的错误,但是现在我似乎无法从它读取的行中删除 DataDir,我尝试使用“pop " 并以与读取文件相同的方式读取数组,但它还没有工作。

标签: regex perl path


【解决方案1】:

当 Perl 看到字符串 "C:\backups\MySQL\my.txt" 时,它会尝试解析任何转义序列,例如 \n。但是当它在\my.txt 中看到\m 时,这是一个无法识别的转义序列,因此会出现错误。

解决此问题的一种方法是正确转义反斜杠:"C:\\backups\\MySQL\\my.txt"。解决此问题的另一种方法是使用单引号而不是双引号:'C:\backups\MySQL\my.txt'。然而另一种方法是使用q() 构造:q(C:\backups\MySQL\my.txt)

【讨论】:

  • 我也尝试了您的解决方案,它确实有效,但是我仍然遇到“错误,找不到 my.txt。”的问题,但到目前为止感谢!
  • @perlnoob:你确定文件存在并且可读吗?
  • 是的,这是该目录的输出:C:\backups\mysql 04/09/2010 08:40 AM 的目录。 04/09/2010 08:40 AM .. 04/09/2010 08:45 AM 58 my.txt 即使在 perl 脚本中将其更改为小写也不会有任何变化。例如,如果我开始 > 运行并输入:C:/backups/MySQL/my.txt,它会打开带有文本文件的记事本
  • @perlnoob:将您的错误消息更改为包含$!,以便您看到操作系统在打开文件失败时实际返回的错误。
  • Ryan Zachry 提供的解决方案解决了这个问题。感谢您迄今为止的帮助!
【解决方案2】:

由于存在几个问题,我会将 cmets 放在我在下面代码中所做的更改上。

use strict; 
use warnings;
# For pretty dumping of arrays and what not.
use Data::Dumper;

# Use single quotes so you don't have to worry about escaping '\'s.
# Use a scalar ($) instead of an array(@) for storing the string.
my $myfile = 'C:\backups\MySQL\my.txt';

# No need to initialize the array.
my @datadir;

# I believe using a scalar is preferred for file handles.
# $! will contain the error if we couldn't open the file.
open(my $readmyfile, $myfile) or die "error opening: $!";

while (<$readmyfile>) {
    # You must escape '\'s by doubling them.
    # If you are just testing to see if the line contains 'c:\backups' you do not
    # need /g for the regex. /g is for repeating matches
    if (/C:\\backups/i) {
        push(@datadir, $_);
    }
}

# Data::Dumper would be better for dumping the array for debugging.
# Dumper wants a reference to the array.
print Dumper(\@datadir);

更新:

如果您指的是 Data::Dumper 的输出,它只是为了漂亮地表示数组。如果您需要特定格式的输出,则必须对其进行编码。开始是:

print "$_\n" for (@datadir);

【讨论】:

  • 这几乎完成了我想要的一切,但是我希望在 dir 和它的 "DataDir=" 部分周围加上引号,但到目前为止这是最好的答案。
【解决方案3】:

使用正斜杠代替反斜杠

【讨论】:

  • 非常好,这解决了“在 1130.pl 第 17 行通过的无法识别的转义 \m”。错误,但是我仍然没有收到“错误,找不到 my.txt”。由于某种原因仍然出现。
【解决方案4】:

您不应该使用$myfile 而不是@myfile 吗?后者为您提供了一个数组,并且由于您在标量上下文中引用它,因此它被取消引用(因此它实际上是在尝试打开一个名为 ARRAY(0xdeadbeef) 之类的“文件”而不是实际文件名)。

【讨论】:

    【解决方案5】:

    找不到该文件,因为您将数组传递给open,而它需要一个标量,所以我猜该数组是在标量上下文而不是列表中评估的,所以您实际上是告诉 perl 尝试打开名为 '1' 的文件,而不是你的 'my.txt' 文件。

    试试这样的:

    my $a = 'filename';
    open FH, $a or die "Error, could not open $a: $!";
    ...
    

    【讨论】:

      【解决方案6】:

      正如其他人所说,部分问题是使用 " " 而不是 ' ' 类型的引用。 我总是尝试使用' ',除非我知道我需要包含转义或插入变量。 这里有一些陷阱

          use 5.10.0 ;
          use warnings ;
      
          say "file is c:\mydir" ;
          say "please pay $100 ";
          say "on VMS the system directory is sys$system" ;
          say "see you @5 ";
      

      带双引号

          Unrecognized escape \m passed through at (eval 1) line 2.
          Possible unintended interpolation of @5 in string at (eval 1) line 5.
          file is c:mydir
          Use of uninitialized value $100 in concatenation (.) or string at (eval 1) line 3.
          please pay
          Use of uninitialized value $system in concatenation (.) or string at (eval 1) line 4.
          on VMS the system directory is sys
          see you
      

      带单引号

          file is c:\mydir
          please pay $100
          on VMS the system directory is sys$system
          see you @5
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        相关资源
        最近更新 更多