代码之家  ›  专栏  ›  技术社区  ›  Kurt W. Leucht

如何在Perl中一次处理一行多行字符串,并在适当的位置使用strict?

  •  8
  • Kurt W. Leucht  · 技术社区  · 15 年前

    我正在尝试找出正确的PBP批准的方法来一次处理一行多行字符串。许多Perl编码人员建议将多行字符串视为一个文件句柄,除非脚本中有“use strict”,否则它可以正常工作。然后,编译器会警告您在使用严格引用时不能将字符串用作符号。

    下面是这个问题的一个简单的工作示例:

    #use strict;
    use warnings; 
    
    my $return = `dir`;
    my $ResultsHandle = "";
    my $matchLines = "";
    my $resultLine = "";
    open $ResultsHandle, '<', \$return;
    while (defined ($resultLine = <$ResultsHandle>)) {
        if ($resultLine =~ m/joe/) {
            $matchLines = $matchLines . "\t" . $resultLine;
        }
    }
    close($ResultsHandle);
    print "Original string: \n$return\n";
    print "Found these matching lines: \n$matchLines\n";
    

    注意,“use strict”行被注释掉了。当我在不严格使用的情况下运行此脚本时,我得到了我想要的和期望的:

    Original string: 
     Volume in drive D has no label.
     Volume Serial Number is 50D3-54A6
    
     Directory of D:\Documents and Settings\username\My Documents\Eclipse\myTestProject
    
    09/18/2009  11:38 AM    <DIR>          .
    09/18/2009  11:38 AM    <DIR>          ..
    09/18/2009  11:36 AM               394 .project
    09/18/2009  11:37 AM                 0 joe.txt
    09/18/2009  11:37 AM                 0 joey.txt
    09/18/2009  11:38 AM                 0 kurt.txt
    09/18/2009  11:43 AM               497 main.pl
    09/18/2009  11:38 AM                 0 shane.txt
                   6 File(s)            891 bytes
                   2 Dir(s)   6,656,188,416 bytes free
    
    Found these matching lines: 
        09/18/2009  11:37 AM                 0 joe.txt
        09/18/2009  11:37 AM                 0 joey.txt
    

    但问题是。当我取消对“use strict”行的注释时,Perl会发出以下警告或错误:

    Can't use string ("") as a symbol ref while "strict refs" in use at D:/Documents and Settings/username/My Documents/Eclipse/myTestProject/main.pl line 8.
    

    第8行是“open$resultshandle,<',\$return;”行。因此,由于Perl最佳实践要求我使用严格的方法,PBP如何期望我一次处理一行多行字符串?SO社区有什么建议吗?

    谢谢!

    7 回复  |  直到 15 年前
        1
  •  11
  •   dave4420    15 年前

    不初始化 $ResultsHandle :

    use strict;
    use warnings; 
    
    my $return = `dir`;
    my $ResultsHandle;  # <-- leave undefined
    my $matchLines = "";
    my $resultLine = "";
    open $ResultsHandle, '<', \$return;
    while (defined ($resultLine = <$ResultsHandle>)) {
        if ($resultLine =~ m/joe/) {
            $matchLines = $matchLines . "\t" . $resultLine;
        }
    }
    close($ResultsHandle);
    print "Original string: \n$return\n";
    print "Found these matching lines: \n$matchLines\n";
    

    如果你离开 硕果累累 在之前未定义 open() ,它将用对文件句柄的引用填充。因为你把它设置成一个字符串, 打开() 假定它应该是对变量的符号引用,而不允许在 use strict .

        2
  •  7
  •   AndyG    7 年前

    更简洁的PBP方法是使用 open 像这样:

    open my $ResultsHandle, '<', \$return;
    

    这就不再需要以前的“我的$resultshandle”;声明,并且避免了 严格的 警告你碰到了。

        3
  •  4
  •   jrockway    15 年前

    还可以使用regexp作为迭代器:

    my $data = q{Hello
    This
    Is
    A
    Test};
    
    while( $data =~ /(.+)$/mg) {
        print "line is '$1'\n";
    }
    

    与使用表示字符串的filehandle相比,这要稍微少一些复杂。

        4
  •  3
  •   mob    15 年前

    将多行字符串转换为具有 split :

    my @resultLines = split /\n/, $result;     #   or  /\r\n/ for Windows?
    foreach my $resultLine (@resultLines) {
        if ($resultLine =~ m/joe/) {
            $matchLines
                = $matchLines . "\t" 
                     . $resultLine . "\n";  # put \n or \r\n back on the end
        }
    }
    
        5
  •  2
  •   moonshadow    15 年前

    变化

    my $ResultsHandle = "";
    

    my $ResultsHandle;
    
        6
  •  0
  •   innaM    15 年前

    使用“dir”命令中的管道打开文件句柄。

    例如。

    open my $FOO, "dir|" or die "Can not run 'dir': $!";
    
        7
  •  0
  •   Znik    8 年前

    分割的更好结果可以通过以下方式实现:

    my $result="LINE1
    line2
    linE3
    ";
    #attention, /^/m allows properly operate on multiline string using regex
    #and ^ is character empty begin all lines
    foreach my $resultLine (split /^/m, $result) {
        print $resultline;  #withount '\n' because it have got
        #some checks & operations
    }