perl regex question

C

Chad Williams

my $procspeed="state on-line state_begin 1058768026 cpu_type sparcv9
fpu_type sparcv9 clock_MHz 450";

How come this:

$procspeed=~ s/.*\s(\d+)\w*/$1/;

gives me $procspeed=450

but this:

$procspeed=~ s/.*\s(\d+)\w*$/$1/;

matches the whole line?

What's the most efficient way to do this? (get the last word/word of
digits, etc)

TIA
 
M

Matija Papec

X-Ftn-To: Chad Williams

my $procspeed="state on-line state_begin 1058768026 cpu_type sparcv9
fpu_type sparcv9 clock_MHz 450";

How come this:

$procspeed=~ s/.*\s(\d+)\w*/$1/;

gives me $procspeed=450

but this:

$procspeed=~ s/.*\s(\d+)\w*$/$1/;

matches the whole line?

What's the most efficient way to do this? (get the last word/word of
digits, etc)

Don't know for most efficient but this is the simplest :)
print ($procspeed =~ /(\d+)/g)[-1]
 
J

John W. Krahn

Chad said:
my $procspeed="state on-line state_begin 1058768026 cpu_type sparcv9
fpu_type sparcv9 clock_MHz 450";

How come this:

$procspeed=~ s/.*\s(\d+)\w*/$1/;

gives me $procspeed=450

but this:

$procspeed=~ s/.*\s(\d+)\w*$/$1/;

matches the whole line?

They both match the same thing. The $ anchor doesn't make a difference
because the .* at the beginning is greedy.


John
 
G

Glenn Jackman

Chad Williams said:
my $procspeed="state on-line state_begin 1058768026 cpu_type sparcv9 fpu_type sparcv9 clock_MHz 450"; [...]
What's the most efficient way to do this? (get the last word/word of
digits, etc)

Also,
my ($last_digits) = $procspeed =~ m{
(\d+) # a sequence of digits
\D*$ # followed by non-digits at the end of the string
}x;
 
J

Jeff 'japhy' Pinyan

[posted & mailed]

my $procspeed="state on-line state_begin 1058768026 cpu_type sparcv9
fpu_type sparcv9 clock_MHz 450";

How come this:

$procspeed=~ s/.*\s(\d+)\w*/$1/;

gives me $procspeed=450

but this:

$procspeed=~ s/.*\s(\d+)\w*$/$1/;

matches the whole line?

They should both result in $procspeed being 450. (They do for me.)
What's the most efficient way to do this? (get the last word/word of
digits, etc)

You can use the .* approach, but you need to be sure you write it
properly. You did, ensuring there's a space before the digits. If you
had left it out, $procspeed would only be '0', since the .* is greedy, and
(\d+) is content in just matching one digit.

I wouldn't suggest the /(\d+)\D*$/ approach, because it requires you try
to match at EACH chunk of digits. If there are many chunks of digits in
your string, that'll be inefficient.

I personally suggest reversing the string, matching the "first" set of
digits, and then reversing that match.

$last_num = reverse( (reverse($str) =~ /(\d+)/)[0] );

Or:

$last_num = reverse $1 if reverse($str) =~ /(\d+)/;
 
Q

Quantum Mechanic

What's the most efficient way to do this? (get the last word/word of
digits, etc)

Generally slower to faster options:

$last_word = ($string =~ /(\w+)/g)[-1]; # only keep the last word

$last_word = reverse ( (reverse $string) =~ /(\w+)/ ); # double reverse

$last_word = (split /\W+/, $string )[-1];

$last_word = reverse( (split /\W+/, reverse $string, 2 )[0] );

-QM
 
M

Matija Papec

I wouldn't suggest the /(\d+)\D*$/ approach, because it requires you try
to match at EACH chunk of digits. If there are many chunks of digits in
your string, that'll be inefficient.

I personally suggest reversing the string, matching the "first" set of
digits, and then reversing that match.

$last_num = reverse( (reverse($str) =~ /(\d+)/)[0] );

I guess index can be left out since list has only one value,
$last_num = reverse( reverse($procspeed) =~ /(\d+)/ );
 

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

Forum statistics

Threads
474,257
Messages
2,571,031
Members
48,768
Latest member
first4landlord

Latest Threads

Top