我正在阅读这个文本文件以获取其中的单词并忽略所有类型的空格:
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
输出显示两个换行符,但我希望输出只是单词。我该怎么办才能得到文字?
答案 0 :(得分:3)
你应该总是 use strict
和use 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次或更多次......