2010-04-08 54 views
1

我很新的Perl,所以請原諒我的簡單的問題串:的Perl:獲得相匹配的正則表達式錯誤

下面是示例輸出:

Most successful agents in the Emarket climate are (in order of success): 
1. agent10896761  ($-8008) 
2. flightsandroomsonly  ($-10102) 
3. agent10479475hv  ($-10663) 
Most successful agents in the Emarket climate are (in order of success): 
1. agent10896761  ($-7142) 
2. agent10479475hv  ($-8982) 
3. flightsandroomsonly  ($-9124) 

我感興趣的只是代理名稱以及他們相應的餘額,所以我希望得到以下輸出:

agent10896761  -8008 
flightsandroomsonly  -10102 
agent10479475hv  -10663 
agent10896761  -7142 
agent10479475hv  -8982 
flightsandroomsonly  -9124 

對於後面的過程。

這是迄今爲止我已經得到了代碼:

#!/usr/bin/perl -w 
open(MYINPUTFILE, $ARGV[0]); 

while(<MYINPUTFILE>) 
{ 
    my($line) = $_; 
    chomp($line); 

    # regex match test 
    if($line =~ m/agent10479475/) 
    { 
     if($line =~ m/($-[0-9]+)/) 
     { 
      print "$1\n"; 
     } 

    } 
    if($line =~ m/flightsandroomsonly/) 
    { 
     print "$line\n"; 
    } 
} 

第二個正則表達式匹配有什麼不妥,因爲那是打印出整條生產線。但是,對於第一個正則表達式匹配,我有一些其他輸出等類

$ ./compareResults.pl 3.txt 
2.  flightsandroomsonly    ($-10102) 
0479475 
0479475 
3.  flightsandroomsonly    ($-9124) 
1.  flightsandroomsonly    ($-8053) 
0479475 
1.  flightsandroomsonly    ($-6126) 
0479475 

如果我「越獄」這樣

if($line =~ m/\($-[0-9]+\)/) 
{ 
    print "$1\n"; 
} 

括號再有就是從不爲第一個比賽正則表達式...

所以我堅持一個問題,使特定的正則表達式的工作。任何提示?提前謝謝了。

回答

3
perl -ane '$F[2]=~s/\(|\)//g;print "$F[1] $F[2]\n" if $F[1]=~/agent|flight/' file 
+0

@ ghostdog74:我從來沒有想到看到一個襯墊的解決方案。哇,謝謝你的提示。我可以在這裏看到邏輯。 – 2010-04-08 14:56:05

+0

Kool one-liner :) – Mike 2010-04-08 15:31:59

4

請記住,正則表達式中的$是字符串末尾的錨點。將其轉義爲與字面美元符號字符相匹配。

我會寫這樣說:

#! /usr/bin/perl 

use warnings; 
use strict; 

# for demo only 
*ARGV = *DATA; 

my $agent = qr/ 
^\s* \d+ \. # item number at the beginning of line 
    \s+ 
    (\S+)   # agent name into $1 
    \s+ 
    \(\s* \$ \s* # start of balance 
    (-?\d+)  # balance into $2 
    \s* \)   # end of balance 
    \s* $   # optional whitespace at the tail 
/x; 
while (<>) { 
    if (my ($name,$balance) = /$agent/) { 
    printf "%-20s : %d\n", $name, $balance; 
    } 
} 

__DATA__ 
Most successful agents in the Emarket climate are (in order of success): 
1. agent10896761  ($-8008) 
2. flightsandroomsonly  ($-10102) 
3. agent10479475hv  ($-10663) 
Most successful agents in the Emarket climate are (in order of success): 
1. agent10896761  ($-7142) 
2. agent10479475hv  ($-8982) 
3. flightsandroomsonly  ($-9124) 

輸出:

agent10896761  : -8008 
flightsandroomsonly : -10102 
agent10479475hv  : -10663 
agent10896761  : -7142 
agent10479475hv  : -8982 
flightsandroomsonly : -9124

不要讓*ARGV = *DATA線嚇唬你。這使我可以在不改變處理邏輯的情況下將程序及其輸入組合在一個文件中。在您的代碼中,您將刪除該行,然後以與之前相同的方式運行您的程序,例如

$ ./compareResults.pl input.txt
+0

@gbacon:感謝這個優秀的例子 – 2010-04-08 22:19:41

+0

@Michael不客氣!我希望它有幫助。 – 2010-04-08 23:20:04

1
use strict; 
use warnings; 

while(<DATA>){ 
    #split on whitespaces, pick 2nd and 3rd items 
#check 2nd item matches pattern, do some trimming to 3rd 
#store them to @data and print them 
    my @data =grep{/\w{13,}/ || s/\(\$|\)//g;}((split' ')[1,2]); 
    print join("\t",@data),"\n" if (@data); 

} 


__DATA__ 
1. agent10896761  ($-8008) 
2. flightsandroomsonly  ($-10102) 
3. agent10479475hv  ($-10663) 
Most successful agents in the Emarket climate are (in order of success): 
1. agent10896761  ($-7142) 
2. agent10479475hv  ($-8982) 
3. flightsandroomsonly  ($-9124) 

__OUTPUT__ 
agent10896761 -8008 
flightsandroomsonly  -10102 
agent10479475hv -10663 
agent10896761 -7142 
agent10479475hv -8982 
flightsandroomsonly  -9124 
+0

@Mike:感謝這個提示,看起來很可能是我從uni學習的方式。 – 2010-04-09 04:04:11