繁体   English   中英

使用Perl正则表达式解析制表符分隔的文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM