我试图弄清楚如何使用正则表达式能够从制表符分隔的文本文件中“提取”特定文本,并对下面的文件执行操作。
我有一个文件格式如下:
#HEADER_IGNORE HEADING1 HEADING2 HEADINGN
Some Text Here value value2 value3
SOME_TEXTHERE x z
Some More Text Here A B
我希望能够提取第一个“专栏”。基本上,我想在第一个选项卡之前获取所有文本,以便我的正则表达式能够提取:
Some Text Here
SOME_TEXTHERE
Some More Text Here
我试图使用以下正则表达式而没有任何运气。
/(\W\s)*\t$/
现在我希望能够做的第二件事就是告诉任何行x列引用是否缺少值。即在上面的示例文件中,行标识SOME_TEXTHERE
缺少HEADING2
的值。可能有任意数量的行ID和列。
提前致谢!
答案 0 :(得分:1)
经典的方法是chomp
每一行删除行终止符,然后split /\t/
提取所有字段值的列表。
chomp;
my @fields = split /\t/;
my $field1 = $fields[0];
但是,如果您确定只有曾想要第一列,最简单的方法是找到不是的行开头的所有字符标签。
my ($field1) = /\A([^\t]+)/;
鉴于您的第二个要求,其中第一个是最好的。这取决于“缺失值”的含义,但只要所有制表符分隔符在那里,您就可以通过编写来检查以确保一行具有给定数量的字段
my $n = grep /\S/, @fields;
warn "Missing field" unless $n == 4;
或者,如果您想要发现哪个字段缺失,那么
my @missing = map { $fields[$_-1] !~ /\S/ } 1 .. 4;
warn "Missing field $missing[0]" if @missing;
答案 1 :(得分:-1)
我是哈希的忠实粉丝,所以我会使用哈希
因为如果缺少数组中的最后一个元素,split
不起作用,如果最后一个元素是\t
,我们必须手动添加一个空字符串(这样缺少的列将变为空字符串)。
例如,如果$rows{SOME_TEXTHERE}[1] eq ""
#!/usr/bin/perl
use strict;
use warnings;
chomp(my $first_line = <STDIN>);
my $length = scalar(split /\t/, $first_line);
my %rows;
while (<STDIN>) {
chomp;
my @row = split /\t/;
push @row, "" for 1..$length - scalar @row;
# Assuming there's ALWAYS a row ID
my $id = shift @row;
$rows{$id} = [@row];
}
foreach my $rowID (keys %rows) {
for (my $i = 0; $i < @{$rows{$rowID}}; $i++) {
# Column 1 being the id
printf "missing column #%d in %s\n", $i + 1, $rowID
if $rows{$rowID}[$i] eq "";
}
}