1

我试图弄清楚如何使用正则表达式能够从制表符分隔的文本文件中“提取”特定文本并对下面的文件执行操作。

我有一个格式如下的文件:

#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 列引用是否缺少值。即在上面的示例文件中,行 idSOME_TEXTHERE缺少HEADING2. 可能有任意数量的行 ID 和列。

提前致谢!

4

2 回答 2

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;
于 2013-10-09T21:36:42.443 回答
-1

我是哈希的忠实粉丝,所以我会使用哈希。
因为split如果数组中的最后一个元素丢失了就不起作用了,所以如果最后一个元素是a,我们必须手动添加一个空字符串\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 "";
    }
}
于 2013-10-09T21:56:41.173 回答