Perl,Pattern匹配数组中的每个元素($ line)

时间:2013-03-20 14:11:51

标签: arrays perl design-patterns matching

我认为我有一个简单的问题,我最近运行了一个脚本,该脚本从数组中每个元素的字符串中提取特定信息。我以前写过这个并且它运行良好但是当它现在尝试它的非常简单的版本它不会只提供相同的响应未初始化的值参数!因为我以前的代码工作,我真的很沮丧。我显然做了一些愚蠢的事情,并希望得到一些帮助!

#!/usr/bin/env perl

use strict;
use warnings;


my@histone;
my$line;
my$idea;
my$file="demo_site.txt";

open(IN, "<$file")||die"\ncannot be opend\n";

@histone=<IN>;
print @histone;

foreach $line(@histone)
       {
           $line=~ m/([a-zA-Z0-9]+)\t[0-9]+\t[0-9]+\t/;

           print$1."\n";
           print$2."\n";
           print$3."\n";

       }

infile&#34; demo_site.txt&#34;采用制表符分隔的.txt文件的格式:

chr9        1234       5678     .     200      .      14.0      -1

这个文件有多行如上所述,我想提取前三项数据,所以输出如下:

chr9
1234
5678

干杯!

5 个答案:

答案 0 :(得分:3)

你真的不需要正则表达式,因为它是以制表符分隔的。

foreach $line(@histone)
       {
           @line_data = split(/\t/,$line)

           print $line_data[0]."\n";
           print $line_data[1]."\n";
           print $line_data[2]."\n";

       }

编辑:
如果要将值分配给特定的命名变量,请将其分配给临时数组。

($varA, $varB, $varC .... ) = split(/\t/,$line)

答案 1 :(得分:2)

这里的实际问题是您尝试打印$1$2$3的值,但在正则表达式中只有一组捕获括号,所以只有$1获得一个值。 $2$3将保持未定义状态,因此在您尝试打印时会出现错误。

解决方案是再添加两组捕获括号。我希望你想要这样的东西:

$line=~ m/([a-zA-Z0-9]+)\t([0-9]+)\t([0-9]+)\t/;

答案 2 :(得分:1)

我们假设file.txt有你想要的东西:(file.txt eq demo_site.txt

chr9        1234       5678     .     200      .      14.0      -1

你可以使用简单的东西:

perl -ane '$" = "\n"; print "@F[0..2]"' file.txt 1>output.txt

Perl中的单行是强大的。而且您不需要为简单的任务编写脚本;)

有时候打开终端;)

P.S:

这不是很好的单行,我知道,但它做了它必须做的事。

答案 3 :(得分:0)

$ line = ~m /([a-zA-Z0-9] +)\ t [0-9] + \ t [0-9] + \ t /)

首先,parens不平衡。

其次,我没有检查过这个,但是你不是每次捕获都需要一套parens吗?

第三,因为misplacedme说split()绝对是要走的路。 ;)

答案 4 :(得分:0)

如果我可以自我推销,您可以使用Tie::Array::CSV直接读写文件作为外部数组的arrayrefs。

use strict;
use warnings;
use Tie::Array::CSV;
tie my @file, 'Tie::Array::CSV', 'demo_site.txt', sep_char => "\t";

print $file[0][0]; # first line before first tab
$file[2][1] = 10; # set the third line between the first and second tabs