[英]Parsing a tab delimited file using Perl regular expressions
我试图弄清楚如何使用正则表达式来“提取”从制表符分隔的文本文件中的特定文本,并对下面的文件执行操作。
我有一个以下格式的文件:
#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列引用都缺少值。 即,在前面的示例文件,行ID SOME_TEXTHERE
缺少的值HEADING2
。 可能有任意数量的行ID和列。
提前致谢!
经典方法是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;
我是哈希的忠实拥护者,所以我会使用哈希。
由于如果缺少数组中的最后一个元素,则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 "";
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.