Perl : get substring which matches regex error
I am very new to Perl, so please bear with my simple question:
Here is the sample output:
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)
I am interested only in agent names as well as their corresponding balances, so I am hoping to get the following output:
agent10896761 -8008
flightsandroomsonly -10102
agent10479475hv -10663
agent10896761 -7142
agent10479475hv -8982
flightsandroomsonly -9124
For later processes.
This is the code I've got so far:
#!/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";
}
}
The second regex match has nothing wrong, 'cause that is printing out the whole line. However, for the first regex match, I've got some other output such like:
$ ./compareResults.pl 3.txt
2. 开发者_开发百科 flightsandroomsonly ($-10102)
0479475
0479475
3. flightsandroomsonly ($-9124)
1. flightsandroomsonly ($-8053)
0479475
1. flightsandroomsonly ($-6126)
0479475
If I "escape" the braces like this
if($line =~ m/\($-[0-9]+\)/)
{
print "$1\n";
}
Then there is never a match for the first regex...
So I'm stuck with a problem of making that particular regex work. Any hints for this? Many thanks in advance.
Remember that $
in a regular expression is an anchor at the end of the string. Escape it to match a literal dollar-sign character.
I'd write it this way:
#! /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)
Output:
agent10896761 : -8008 flightsandroomsonly : -10102 agent10479475hv : -10663 agent10896761 : -7142 agent10479475hv : -8982 flightsandroomsonly : -9124
Don't let the *ARGV = *DATA
line scare you. That allows me to have the program and its input together in a single file without changing the processing logic. In your code, you'd remove that line and then run your program in the same way as before, e.g.,
$ ./compareResults.pl input.txt
perl -ane '$F[2]=~s/\(|\)//g;print "$F[1] $F[2]\n" if $F[1]=~/agent|flight/' file
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
精彩评论