Extract a number from a string.

A

Adam

Hi All,

Apologies if this is laughably simple, but it's been a long time since
I've used Perl, and I seem to suffer from Homer Simpson's problem:
every time I learn something new, it pushes old stuff out.

I'm trying to extract a number from a line of text returned by a
license-checking command. I open a pipe to the command, and read
through each line that is returned. When I find the text "Maximum..."
or "Current..." I want to extract and store the number in that line. I
tried using something like this to start with:

$lic_usage{$lic_type}{$max} = /\d+/ if (/Maximum/);
$lic_usage{$lic_type}{$cur} = /\d+/ if (/Current/);

Of course, this only stores a 1 ('True') when it finds the string, and
I want it to record the actual digits.

Help!

Cheers - Adam...
 
P

Peter Wyzl

Adam said:
Hi All,

Apologies if this is laughably simple, but it's been a long time since
I've used Perl, and I seem to suffer from Homer Simpson's problem:
every time I learn something new, it pushes old stuff out.

I'm trying to extract a number from a line of text returned by a
license-checking command. I open a pipe to the command, and read
through each line that is returned. When I find the text "Maximum..."
or "Current..." I want to extract and store the number in that line. I
tried using something like this to start with:

$lic_usage{$lic_type}{$max} = /\d+/ if (/Maximum/);
$lic_usage{$lic_type}{$cur} = /\d+/ if (/Current/);

You need to capture the numbers IF there is a match...

if (/Maximum/){$lic_usage{$lic_type}{$max} = $1 if (/(\d+)/)};

Because there are two conditionals involved (you don't want to assign from
$1 et al unless there was a match) I would write it like the above, or
perhaps less ambiguously like:

if (/Maximum/){
$lic_usage{$lic_type}{$max} = $1 if (/(\d+)/);
}

Check in perlre for info on the capturing parens.
 
A

Anno Siegel

Adam said:
Hi All,

Apologies if this is laughably simple, but it's been a long time since
I've used Perl, and I seem to suffer from Homer Simpson's problem:
every time I learn something new, it pushes old stuff out.

I'm trying to extract a number from a line of text returned by a
license-checking command. I open a pipe to the command, and read
through each line that is returned. When I find the text "Maximum..."
or "Current..." I want to extract and store the number in that line. I
tried using something like this to start with:

$lic_usage{$lic_type}{$max} = /\d+/ if (/Maximum/);
$lic_usage{$lic_type}{$cur} = /\d+/ if (/Current/);

Of course, this only stores a 1 ('True') when it finds the string, and
I want it to record the actual digits.

Too few parentheses in some places, more than needed in others.

( $lic_usage{ $lic_type}{ $max}) = /(\d+)/ if /Maximum/;

The parentheses around the left side of "=" put the right side
in array context. That makes the regex return the list of captured
matches. The parentheses around "\d+" in the regex capture the
digits. The condition of a statement-modifying "if" doesn't need
parentheses.

Of course, the value of $lic_usage{ $lic_type}{ $max} must be checked
before use, there is no guarantee that the statement ever assigns
anything.

Anno
 
A

Adam

Peter Wyzl said:
You need to capture the numbers IF there is a match...

if (/Maximum/){$lic_usage{$lic_type}{$max} = $1 if (/(\d+)/)};

Because there are two conditionals involved (you don't want to assign from
$1 et al unless there was a match) I would write it like the above, or
perhaps less ambiguously like:

if (/Maximum/){
$lic_usage{$lic_type}{$max} = $1 if (/(\d+)/);
}

Check in perlre for info on the capturing parens.

Thank you Peter (and anyone else who answers before Google gets this
reply out)...

It was indeed because I had omitted the parentheses around '\d+' -
although I discovered it *is* possible to present it as a single line
by assigning the lic_usage hash in list context, thus:

($lic_usage{$lic_type}{$max}) = /(\d+)/ if (/Maximum/);

I was so nearly there!

Thanks again - Adam...
 
J

John W. Krahn

Adam said:
Apologies if this is laughably simple, but it's been a long time since
I've used Perl, and I seem to suffer from Homer Simpson's problem:
every time I learn something new, it pushes old stuff out.

I'm trying to extract a number from a line of text returned by a
license-checking command. I open a pipe to the command, and read
through each line that is returned. When I find the text "Maximum..."
or "Current..." I want to extract and store the number in that line. I
tried using something like this to start with:

$lic_usage{$lic_type}{$max} = /\d+/ if (/Maximum/);
$lic_usage{$lic_type}{$cur} = /\d+/ if (/Current/);

Of course, this only stores a 1 ('True') when it finds the string, and
I want it to record the actual digits.

$lic_usage{$lic_type}{$max} = $1 if /Maximum/ && /(\d+)/;
$lic_usage{$lic_type}{$cur} = $1 if /Current/ && /(\d+)/;



John
 
D

David Filmer

Out of curiosity, are you trying to parse the output from IBM's LUM
(i4lls/i4blt) license manager?
 
P

Peter Wyzl

Adam said:

($lic_usage{$lic_type}{$max}) = /(\d+)/ if (/Maximum/);

What happens here when /Maximum/ matches and /(\d+)/ fails to capture
anything?

You end up assigning whatever happens to be in $1 at that time (maybe
nothing, more likely the result of the last successful match) to
$lic_usage{$lic_type}{$max}. This is a _bad_ thing.

That is precisely why I showed it as two separate matches. See John Krahn's
post for a nice way to do both conditionals in a single line without that
risk.
 
B

Ben Morrow

Quoth "Peter Wyzl said:
What happens here when /Maximum/ matches and /(\d+)/ fails to capture
anything?

You end up assigning whatever happens to be in $1 at that time (maybe
nothing, more likely the result of the last successful match) to
$lic_usage{$lic_type}{$max}. This is a _bad_ thing.

Did you try it? You actually get the empty string.

You should never use the $n variables without checking the match
succeeded, but list assognment of a match does not use the $n variables.

Ben
 
P

Peter Wyzl

Ben Morrow said:
Did you try it? You actually get the empty string.

You should never use the $n variables without checking the match
succeeded, but list assognment of a match does not use the $n variables.

No, I didn't try it cos I was making the point that it was 'a bad thing'(tm)
and not what I had replied with earlier.
 
B

Ben Morrow

Quoth Brian McCauley said:
Did you try it? You actually get the undefined value. :)

I did, actually, but I missed the brackets around $y in

my ($y) = /(\d+)/ if /Maximum/;

so I got the empty string instead... whoops. :)

Ben
 

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,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top