为什么我的Perl代码不会省略换行符?

时间:2012-10-06 11:45:37

标签: perl

我正在阅读这个文本文件以获取其中的单词并忽略所有类型的空格:

hello
now
    do you see this.sadslkd.das,msdlsa but 
      i   hoohoh

这是我的Perl代码:

#!usr/bin/perl -w
require 5.004;

open F1, './text.txt';

while ($line = <F1>) {

    #print $line;
    @arr = split /\s+/, $line;
    foreach $w (@arr) {

        if ($w !~ /^\s+$/) {

            print $w."\n";
        }
    }
    #print @arr;
}
close F1;

这是输出:

hello
now

do
you
see
this.sadslkd.das,msdlsa
but

i
hoohoh

输出显示两个换行符,但我希望输出只是单词。我该怎么办才能得到文字?

3 个答案:

答案 0 :(得分:3)

你应该总是 use strictuse warnings(优先于-w命令行限定符)在每个Perl程序的顶部,并声明每个使用my在其第一个使用点变量。这样,Perl会告诉您可能忽略的简单错误。

您还应该使用具有三参数形式open的词法文件句柄,并检查状态以确保它成功。明确关闭输入文件没有什么意义,除非您希望程序运行一段时间,因为Perl将在退出时为您关闭所有文件。

你真的需要require Perl v5.4吗?那个版本已经十五岁了,如果有比这更旧的东西那么你有一个博物馆!

你的程序会更好:

use strict;
use warnings;

open my $fh, '<', './text.txt' or die $!;

while (my $line = <$fh>) {

    my @arr = split /\s+/, $line;

    foreach my $w (@arr) {
        if ($w !~ /^\s+$/) {
            print $w."\n";
        }
    }
}

注意:道歉。 warnings pragma和lexical文件句柄仅在v5.6中引入,因此我的部分答案无关紧要。最新版本的Perl是v5.16,你真的应该升级

正如Birei指出的那样,问题在于,当行具有前导空格时,在第一个分隔符之前有一个空字段。想象一下,如果您的数据以逗号分隔,那么如果该行以逗号开头,您可能希望Perl报告一个前导空字段。

要提取所有非空格字符,您可以使用完全相同的正则表达式

my @arr = $line =~ /\S+/g;

这可以通过使用split默认参数进行模拟,my @arr = $line =~ split ' ', $line; 是一个引用的空间(不是常规表达)

split

在这种情况下,awk的行为与$_实用程序类似,并按预期丢弃任何前导空字段。

如果让Perl在读取循环中使用split变量,这甚至更简单,因为while (<F1>) { my @arr = split; foreach my $w (@arr) { print "$w\n" if $w !~ /^\s+$/; } } 的所有参数都可以默认:

{{1}}

答案 1 :(得分:2)

这一行是问题所在:

@arr=split(/\s+/,$line);

\s+在前导空格之前进行匹配。请改用' '

@arr=split(' ',$line);

答案 2 :(得分:1)

我相信这一行:

if(!($w =~ /^\s+$/))

您想询问此行中是否有任何内容 - 请勿打印。 但是REGEX中的“+”实际上迫使它至少有一个空间。

如果您将“\ s +”更改为“\ s *”,您会看到它正在运行。因为*是0次或更多次......