0

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

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

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

4

3 回答 3

3

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

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

你真的需要requirePerl v5.4 吗?那个版本是 15 年的,如果安装了比那个版本更旧的东西,那么你就有了博物馆!

你的程序会像这样更好:

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编译指示和词法文件句柄仅在 v5.6 中引入,因此我的部分答案是无关紧要的。Perl 的最新版本是 v5.16,你真的应该升级

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

要提取所有非空格字符,您可以使用正则表达式来完成该操作

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

这可以通过使用单引号空格(不是正则表达式)的默认参数来模拟split

my @arr = $line =~ split ' ', $line;

在这种情况下,它split的行为类似于awk实用程序,并按照您的预期丢弃任何前导的空字段。

如果让 Perl$_在读取循环中使用变量,这会更简单,因为所有参数 forsplit都可以默认:

while (<F1>) {
    my @arr = split;
    foreach my $w (@arr) {
        print "$w\n" if $w !~ /^\s+$/;
    }
}
于 2012-10-06T13:56:37.183 回答
2

这条线是问题所在:

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

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

@arr=split(' ',$line);
于 2012-10-06T11:53:46.790 回答
1

我相信在这一行:

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

您想问这行是否没有任何内容 - 不要打印它。但 REGEX 中的“+”实际上强制它至少有 1 个空格。

如果您将“\s+”更改为“\s*”,您会发现它正在工作。因为 * 是 0 次或更多...

于 2012-10-06T11:56:11.373 回答