Extract a number from a string.

Discussion in 'Perl Misc' started by Adam, Nov 8, 2004.

  1. Adam

    Adam Guest

    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...
    Adam, Nov 8, 2004
    #1
    1. Advertising

  2. Adam

    Peter Wyzl Guest

    "Adam" <> wrote in message
    news:...
    > 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}($_)]}")}}
    Peter Wyzl, Nov 8, 2004
    #2
    1. Advertising

  3. Adam

    Anno Siegel Guest

    Adam <> 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
    Anno Siegel, Nov 8, 2004
    #3
  4. Adam

    Adam Guest

    "Peter Wyzl" <> wrote in message news:<CfIjd.27076$>...
    > "Adam" <> wrote in message
    > news:...
    > > 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...
    Adam, Nov 8, 2004
    #4
  5. 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
    John W. Krahn, Nov 8, 2004
    #5
  6. Adam

    David Filmer Guest

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

    "Adam" <> wrote in message
    news:...
    > 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...
    David Filmer, Nov 9, 2004
    #6
  7. Adam

    Peter Wyzl Guest

    "Adam" <> wrote in message
    news:...
    > "Peter Wyzl" <> wrote in message
    > news:<CfIjd.27076$>...


    <..>

    > ($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';
    Peter Wyzl, Nov 9, 2004
    #7
  8. Adam

    Ben Morrow Guest

    Quoth "Peter Wyzl" <>:
    > "Adam" <> wrote in message
    > news:...
    > > "Peter Wyzl" <> wrote in message
    > > news:<CfIjd.27076$>...

    >
    > <..>
    >
    > > ($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.
    The Levellers, 'Believers'
    Ben Morrow, Nov 9, 2004
    #8
  9. Ben Morrow wrote:

    > Quoth "Peter Wyzl" <>:
    >
    >>"Adam" <> wrote in message
    >>news:...
    >>
    >>>"Peter Wyzl" <> wrote in message
    >>>news:<CfIjd.27076$>...

    >>
    >><..>
    >>
    >>>($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. :)
    Brian McCauley, Nov 9, 2004
    #9
  10. Adam

    Peter Wyzl Guest

    "Ben Morrow" <> wrote in message
    news:...
    >
    > Quoth "Peter Wyzl" <>:
    >> "Adam" <> wrote in message
    >> news:...
    >> > "Peter Wyzl" <> wrote in message
    >> > news:<CfIjd.27076$>...

    >>
    >> <..>
    >>
    >> > ($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";
    Peter Wyzl, Nov 10, 2004
    #10
  11. Adam

    Ben Morrow Guest

    Quoth Brian McCauley <>:
    >
    >
    > Ben Morrow wrote:
    >
    > > Quoth "Peter Wyzl" <>:
    > >
    > >>"Adam" <> wrote in message
    > >>news:...
    > >>
    > >>>"Peter Wyzl" <> wrote in message
    > >>>news:<CfIjd.27076$>...
    > >>
    > >><..>
    > >>
    > >>>($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. :)


    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

    --
    Heracles: Vulture! Here's a titbit for you / A few dried molecules of the gall
    From the liver of a friend of yours. / Excuse the arrow but I have no spoon.
    (Ted Hughes, [ Heracles shoots Vulture with arrow. Vulture bursts into ]
    /Alcestis/) [ flame, and falls out of sight. ]
    Ben Morrow, Nov 11, 2004
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. mark
    Replies:
    1
    Views:
    501
    Victor Bazarov
    Jun 14, 2004
  2. Horacius ReX
    Replies:
    4
    Views:
    302
    Sion Arrowsmith
    Dec 21, 2007
  3. Dwight Army of Champions
    Replies:
    0
    Views:
    391
    Dwight Army of Champions
    Apr 20, 2010
  4. Jochen Brenzlinger
    Replies:
    5
    Views:
    671
    Daniel Pitts
    Nov 21, 2011
  5. Looden

    extract number from binary string

    Looden, Mar 1, 2010, in forum: Perl Misc
    Replies:
    6
    Views:
    192
Loading...

Share This Page