Beginner: regex-error?

M

Marek Stepanek

Hello happy Perlers,


it is very strange: I capture a string as I used it many times, and a
Boolean value is given back. All the day I meditated over this script, but
something very obvious I am missing.

Have a nice evening and sorry for this question


marek

############


#!/usr/bin/perl


use warnings;
use strict;

my (@lines);


while (<DATA>)
{
chomp;
push @lines, $_;
}

foreach my $line (@lines)
{
my $date = $line =~ /^([\d.]+)/;
# why is this regex wrong?
# I want to capture the dates: 17.07.2006 ...
print "\n$date";
}


__DATA__
17.07.2006 CC mU 58.00
17.07.2006 Fr. Knorr CC mU 60.00
18.07.2006 Unterföhring MUC Link CC mU 45.00
19.07.2006 CC mU 58.00
20.07.2006 MUC Hanauer Hermann/Wacki CC mU 55.00
21.07.2006 Claudio/Rock CC oU 55.00
24.07.2006 CC mU 54.00
24.07.2006 CC mU 50.00
24.07.2006 CC mU 55.00
25.07.2006 CC mU 82.00
26.07.2006 -3.7 Uhr! Königin MUC Wacki Bar oU 55.00
27.07.2006 hin rück Link CC mU 122.00
 
P

Paul Lalli

Marek said:
my $date = $line =~ /^([\d.]+)/;
# why is this regex wrong?
# I want to capture the dates: 17.07.2006 ...


A pattern match in scalar context returns either true or false (really,
1 or ""). If you want it to return a list of the sub-captures, you need
to provide list context.

my ($date) = $line =~ /^([\d.]+)/;

The parentheses are not optional.

Paul Lalli
 
K

Keith Keller

it is very strange: I capture a string as I used it many times, and a
Boolean value is given back.

That's because you've asked for a boolean.
my $date = $line =~ /^([\d.]+)/;
# why is this regex wrong?
# I want to capture the dates: 17.07.2006 ...

Read perldoc perlop (not perldoc perlre), search for the string PATTERN,
and read down about m/PATTERN/cgimosx about what the match actually
returns in scalar versus list context. (Hint: you need list context
here.)

--keith
 
M

Marek Stepanek

Marek said:
my $date = $line =~ /^([\d.]+)/;
# why is this regex wrong?
# I want to capture the dates: 17.07.2006 ...


A pattern match in scalar context returns either true or false (really,
1 or ""). If you want it to return a list of the sub-captures, you need
to provide list context.

my ($date) = $line =~ /^([\d.]+)/;

The parentheses are not optional.

Paul Lalli

Thank you Paul,


this was a quick answer to a silly question. But I would never imagined this
answer. Have to learn a lot again.


good night


marek
 
J

John W. Krahn

A. Sinan Unur said:
#!/usr/bin/perl

use warnings;
use strict;

LINE: while ( my $line = <DATA>) {
chomp $line;
last LINE unless length $line;
^^^^^^^^^
Don't you mean:

next LINE
my ($date) = ( $line =~ /^(\d{2}\.\d{2}\.\d{4})/ );
print "$date\n" if defined $date;
}

Or more simply:

LINE: while ( my $line = <DATA> ) {
next LINE unless $line =~ /^(\d{2}\.\d{2}\.\d{4})/;
print "$1\n" if $1;
}

And using defaults:

while ( <DATA> ) {
next unless /^(\d{2}\.\d{2}\.\d{4})/;
print "$1\n" if $1;
}




John
 
A

anno4000

Paul Lalli said:
Marek said:
my $date = $line =~ /^([\d.]+)/;
# why is this regex wrong?
# I want to capture the dates: 17.07.2006 ...


A pattern match in scalar context returns either true or false (really,
1 or "").

Not that it matters in this context, but there's more to Perl's false
value. It's a dual-valued SV which behaves like an empty string in
string context but like a 0 in numeric context. Thus

perl -wle '1 + not 1'

doen't warn about a non-numeric operand like it does in

perl -wle '1 + ""'

A boolean true is indistinguishable from the number 1.

Anno
 
D

Dr.Ruud

Marek Stepanek schreef:
[...]
my (@lines);

while (<DATA>)
{
chomp;
push @lines, $_;
}

foreach my $line (@lines)
{
my $date = $line =~ /^([\d.]+)/;
# why is this regex wrong?
# I want to capture the dates: 17.07.2006 ...
print "\n$date";
}
[...]

First you only need one line of code to fill @lines:

@lines = <DATA> ;


But then you still process them one-by-one, so why not just:

#!/usr/bin/perl
use warnings ;
use strict ;

while (<DATA>)
{
print "$1\n" if /^(\d\d[.]\d\d[.]\d{4})\s/ ;
}

__DATA__
17.07.2006 CC mU 58.00
 
N

Nick of course

A. Sinan Unur said:
You don't really need the if $1 test, either.
In fact it's the unless test that's not really needed, e.g.

while (<DATA>) {
print "$1\n" if /^(\d{2}\.\d{2}\.\d{4})/;
}

or even...

/^(\d{2}\.\d{2}\.\d{4})/ and print "$1\n" while <DATA>;

but don't do this at home
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top