0

我有一个包含一些数据的文本文件。我正在尝试 仅在 ID 列中搜索 EA并打印整行。但代码识别所有 EA 并打印所有行。我应该添加什么代码来满足条件?再次感谢:-)!

数据:
姓名 年龄 ID
---------------------
KRISTE,22, EA 2008
J EA N,21,ES4567
JAK,45, EA 2008

代码打印:
KRISTE ,22, EA 2008
J EA N,21,ES4567
JAK,45, EA 2008

期望输出:
KRIS,22, EA 2008
Kane,45, EA 2008,

file='save.txt';
open(F,$file)||die("Could not open $file");
while ($line=<F>){
if ($line=~ m/$EA/i) {
my @cells=($f1,$f2,$f3)= split ',',$line;
print "<TD>f1</TD>";
print "<TD>f2</TD>";
print "<TD>f3</TD>";
}
4

6 回答 6

8

brian 和 Jeremy 的代码组合解决了所有问题:

use strict;
use warnings;

my $file = 'save.txt';
open my $fh, "<", $file or die "Could not open $file: $!";

while ($line = <$fh>)
{
    my($f1, $f2, $f3) = split ',', $line;
    if ($f3 =~ m/EA/i)
    {
        print "<TD>$f1</TD>";
        print "<TD>$f2</TD>";
        print "<TD>$f3</TD>";
    }
}

布赖恩用 and 概括了匹配模式,use CGI;my $EA = param('keyword');我取消了它,因为我认为它不适用于这个问题。

于 2008-11-04T07:35:11.287 回答
6

您应该发布您正在使用的实际示例程序来说明问题。这是您的清理程序:

use strict;
use warnings;

use CGI;

my $EA = param('keyword');

my $file = 'save.txt';
open my $fh, "<", $file or die "Could not open $file: $!";

while( $line=<$fh> ) {
   if( $line=~ m/$EA/i ) {
       my( $f1, $f2, $f3 ) = split ',', $line;
       print "<TD>$f1</TD>";
       print "<TD>$f2</TD>";
       print "<TD>$f3</TD>";
       }
   }

这里有几件事可以帮助你。

  • 你的变量需要它们的印记。没有他们,他们什么都做不了。
  • 当您尝试打开文件并想报告错误时,请包含 $! 变量,以便您看到错误是什么。
  • 您可以直接拆分为标量变量。这只是一个列表作业。您不需要额外的 @cell 变量。
  • 通过使用一些空格,给你的陈述一些喘息的空间。毕竟,它是免费的。
于 2008-11-04T07:21:21.020 回答
4

你几乎拥有它,我认为这应该工作:

file='save.txt';
open(F,$file)||die("Could not open $file");

while ($line=<F>){
  my @cells=($f1,$f2,$f3)= split ',',$line;
  if ($f3=~ m/$EA/i) {
    print "<TD>f1</TD>";
    print "<TD>f2</TD>";
    print "<TD>f3</TD>";
  }
}

这首先将行拆分为列,然后仅在第三列上执行正则表达式。

顺便说一句,您的代码可能还有其他问题(例如,那些打印语句看起来不像打印变量的值)但我不太了解 perl,所以我只回答了您的主要问题......

于 2008-11-04T05:35:30.810 回答
2

与其尝试自己进行 CSV 解析,不如使用出色而高效的Text::CSV_XS。这将处理转义和引用。

#!/usr/bin/perl -w

use Text::CSV_XS;

my $csv = Text::CSV_XS->new();

# Skip to the data.
while(<DATA>) {
    last if /^-{10,}$/;
}

while( my $row = $csv->getline(*DATA) ) {
    print "@$row\n" if $row->[2] =~ /EA/;
}


__DATA__
Name Age ID
---------------------
KRISTE,22,EA2008
J**EA**N,21,ES4567
JAK,45,EA2008
于 2008-11-06T06:23:15.003 回答
1

或者,您可以更改您的正则表达式以匹配列表中的第三项:

/[^,]*,[^,]*,.*EA/
于 2008-11-04T16:01:49.360 回答
0

您的正则表达式对于您要执行的操作不正确。Ben 的解决方案有效,尽管开头也应该有一个 ^,这确保了正则表达式将从字符串的开头开始匹配:

/^。?,。?,.*EA/

此外,从 perl 的角度来看,您的代码有点嘈杂。如果你想让你的代码更容易阅读,你可以这样做(我正在使用 Ben 的正则表达式):

$f = 'save.txt';

open( F, $file );

@matches = grep { /^.?,.?,.*EA/ } <F>;

现在@matches 将保存你所有匹配的记录,你可以用它们做你想做的事。

于 2008-11-04T17:17:48.130 回答