Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Extract a number from a string.

Reply
Thread Tools

Extract a number from a string.

 
 
Adam
Guest
Posts: n/a
 
      11-08-2004
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...
 
Reply With Quote
 
 
 
 
Peter Wyzl
Guest
Posts: n/a
 
      11-08-2004
"Adam" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> 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.

--
Wyzelli
{{${^_sub}=sub{scalar reverse shift}}{$_={${^_reverse}=>
{${^_scalar}=>{${^_shift}=>{${^_sub}=>{${^_print}= >{}}}}}}
}{s{.*}{rekcaH lreP rehtona tsuJ}}{print("@{[&${^_sub}($_)]}")}}


 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      11-08-2004
Adam <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> 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
 
Reply With Quote
 
Adam
Guest
Posts: n/a
 
      11-08-2004
"Peter Wyzl" <(E-Mail Removed)> wrote in message news:<CfIjd.27076$(E-Mail Removed)>...
> "Adam" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
> > 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.


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...
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      11-08-2004
Adam wrote:
>
> 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
--
use Perl;
program
fulfillment
 
Reply With Quote
 
David Filmer
Guest
Posts: n/a
 
      11-09-2004
Out of curiosity, are you trying to parse the output from IBM's LUM
(i4lls/i4blt) license manager?

"Adam" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> 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...



 
Reply With Quote
 
Peter Wyzl
Guest
Posts: n/a
 
      11-09-2004
"Adam" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> "Peter Wyzl" <(E-Mail Removed)> wrote in message
> news:<CfIjd.27076$(E-Mail Removed)>...


<..>

> ($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.

--
Wyzelli
print '.sig goes here';


 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      11-09-2004

Quoth "Peter Wyzl" <(E-Mail Removed)>:
> "Adam" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
> > "Peter Wyzl" <(E-Mail Removed)> wrote in message
> > news:<CfIjd.27076$(E-Mail Removed)>...

>
> <..>
>
> > ($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.


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

--
If you put all the prophets, | You'd have so much more reason
Mystics and saints | Than ever was born
In one room together, | Out of all of the conflicts of time.
http://www.velocityreviews.com/forums/(E-Mail Removed) The Levellers, 'Believers'
 
Reply With Quote
 
Brian McCauley
Guest
Posts: n/a
 
      11-09-2004


Ben Morrow wrote:

> Quoth "Peter Wyzl" <(E-Mail Removed)>:
>
>>"Adam" <(E-Mail Removed)> wrote in message
>>news:(E-Mail Removed) .com...
>>
>>>"Peter Wyzl" <(E-Mail Removed)> wrote in message
>>>news:<CfIjd.27076$(E-Mail Removed)>...

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

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

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


Did you try it? You actually get the undefined value.

 
Reply With Quote
 
Peter Wyzl
Guest
Posts: n/a
 
      11-10-2004
"Ben Morrow" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> Quoth "Peter Wyzl" <(E-Mail Removed)>:
>> "Adam" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed) om...
>> > "Peter Wyzl" <(E-Mail Removed)> wrote in message
>> > news:<CfIjd.27076$(E-Mail Removed)>...

>>
>> <..>
>>
>> > ($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.

>
> 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.

--
Wyzelli
print "But he didn't listen\n";


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How do i extract vidios when winrar wont extract them??? help plzzzzzzzz smuttdog@sc.rr.com Computer Support 2 12-23-2007 07:03 AM
RegExp to extract letter/number-combination (ANNANN)... Dag Sunde Java 2 11-07-2007 03:11 AM
OT: Number Nine, Number Nine, Number Nine FrisbeeŽ MCSE 37 09-26-2005 04:06 PM
extract number of entries in a line levent C++ 12 08-19-2005 07:18 PM
extract digits from a number ? mark C++ 1 06-14-2004 12:32 AM



Advertisments