尝试从Perl中的文本文件中提取唯一字符串

时间:2018-10-12 09:31:28

标签: regex perl

我在学习Perl时花了5天的时间,遇到了这个问题。 尝试使用正则表达式从文件中提取某个字符串,然后将这些字符串放入苛刻的位置,然后仅输出唯一值,例如,文本文件包含以下字符串:

            "placement Z  F97342"
            "placement d  F97342"
            "placement g  F97342"

预期输出:

             open(FHR, "<test.txt") or die "Cannot open file $!";

            while (<FHR>){

            chomp($_);
            $_ =~/placement/g;

            print "$_\n";

            }

下面是我的代码,但是它给了我重复的带有“ placement Z”的行

{{1}}

有帮助吗?

3 个答案:

答案 0 :(得分:3)

您误解了我想的一堆东西。您正在做一个正则表达式匹配,但实际上并没有对结果做任何事情。

您如何看待:

        $_ =~/placement/g;

在做什么? (因为答案现在是“无”)。

同样-您正在“打印” $_,因此实际上只是在打印文件中的每一行。

您需要在什么级别测试重复项?是“实线”还是仅仅是“展示位置” ID,还是紧随其后的“数字”?

但是,如果您需要测试重复项,那么您需要的是哈希值。

类似这样的方法可以解决问题:

#!/usr/bin/env perl

use strict;
use warnings;

open( my $input, '<', "test.txt" ) or die "Cannot open file $!";

my %seen; 

while (my $line = <$input>) {
   print $line unless $seen{$line}++;
}

也:

  • 使用带有3个参数打开的词法文件句柄的好样式。我的例子反映了这一点。
  • 获取perltidy并使用它。 perltidy -pbp会将代码缩进并格式化为公认的标准。 (您可以根据自己的喜好自定义-格式/缩进可以是任何您想要的,只要它一致即可)。
  • 如果您要做的只是手动重新插入换行符,则无需chomp
  • 您应该始终use strict;use warnings;

如果您希望在测试行的哪一部分上有更多选择,可以使用正则表达式捕获子元素。举例来说-仅“安置信”很重要:

#!/usr/bin/env perl

use strict;
use warnings;

open( my $input, '<', "test.txt" ) or die "Cannot open file $!";

my %seen; 

while ( <$input>) {
   my ( $placement_id ) = m/placement (\d+)/;
   print unless $seen{$placement_id}++;
}

请注意-我没有分配<$input>的内容-它的内容设置为$_,但我觉得作为样式点,您应该避免在代码中使用$_-名称如果您要使用它。

之所以可行,是因为m//正则表达式匹配和print都默认在$_(即“当前行”)上运行。右侧正则表达式中的捕获括号用于填充$placement_id-但请注意,您需要 左侧的括号,否则$placement_id_仅用于模式匹配是否为“真/假”结果。

答案 1 :(得分:2)

在这种情况下,实际上不需要显式打开文件句柄。 Perl将自动打开任何在命令行上给出名称的文件,您可以使用空文件输入运算符(<>)读取其数据。

所以您的代码可以很简单:

#!/usr/bin/perl

use strict;
use warnings;

my %seen;

while (<>) {
  print unless $seen{$_}++;
}

如果此代码位于名为filter的文件中,则可以这样命名:

$ filter test.txt

答案 2 :(得分:1)

使用Perl单线版

> cat file.txt
             "placement Z  F97342"
             "placement Z  F97342"
             "placement d  F97342"
             "placement g  F97342"
             "placement Z  F97342"
> perl -ne  '{ print "$_" unless $data{$_}++; } ' file.txt
             "placement Z  F97342"
             "placement d  F97342"
             "placement g  F97342"
>