markd has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks
I wonder if you can help me. I'm using perl with expect to try and find the 14th number in a line like:

0000: 30 44 02 01 01 04 06 70 75 62 6C 69 63 A7 37 02 0D.....public.7.

in this case its A7. Whats the easiest way of doing this. I am still learning reg expressions and I am having trouble with this one.
Thanks in advance for any help.

Replies are listed 'Best First'.
Re: reg ex help
by pelagic (Priest) on Apr 15, 2004 at 09:46 UTC
    If you know the separator (white space) you don't have to use a regexp. A simple split will do.
    my $line = qq|30 44 02 01 01 04 06 70 75 62 6C 69 63 A7 37 02 0D.....p +ublic.7|; my $fourteenthnumber = (split (/ /, $line))[13]; print $fourteenthnumber;
    updated with tachyon's syntactic sugar from /\s/ to / /.

    pelagic

      FWIW split ' ', $data is magical in that the ' ' matches any quanitity of whitespace ie spaces, tabs, newlines. Syntactic sugar for \s+ really.

      cheers

      tachyon

        FWIW split ' ', $data is magical in that the ' ' matches any quanitity of whitespace ie spaces, tabs, newlines. Syntactic sugar for \s+ really.
        split ' ' and split /\s+/ are not quite the same:
        #!/usr/bin/perl use strict; use warnings; $_ = " foo bar baz "; my @a = split ' '; my @b = split /\s+/; print scalar @a, "\n"; print scalar @b, "\n"; __END__ 3 4

        Abigail

Re: reg ex help
by tachyon (Chancellor) on Apr 15, 2004 at 10:15 UTC

    If you were reading from a stream you could use the input record separator:

    local $/ = " "; while(<DATA>) { next unless $. == 15; # 14th number is 15th element with 0000: f +irst print; last; } __DATA__ 0000: 30 44 02 01 01 04 06 70 75 62 6C 69 63 A7 37 02 0D.....public.7

    cheers

    tachyon

      tachyon's solution would include the space on the end of the number unless you chomp:
      local $/ = " "; while(<DATA>) { next unless $. == 15; # 14th number is 15th element with 0000: f +irst chomp; print; last; } __DATA__ 0000: 30 44 02 01 01 04 06 70 75 62 6C 69 63 A7 37 02 0D.....public.7
      I suppose it depends on what you're using it for later.
        This is what I used and it worked.
        $session1->expect(30, '-re', qr'^0000:.*\r\n'); my $tmpvar = $session1->match(); my $tmpvar1 = (split (/ +/, $tmpvar))[14]; unless($tmpvar1 eq 'A6') { &snmp_conf_cleanup(); &clean_up_and_exit($session,"FAIL",$mesg,"did not receive any +v2 notifications"); }
        My original question to try and match it in one reg exp was to have the code in one expect perl line:
        $session1->expect(30, '-re', qr'REGEX HERE');
        I would still like to do that but at least now I have it working. Thanks for everyone's help here.

        In my defense ;-) that is only if the A7 was followed by a newline of course which it was not in the sample. $/ is probably not the best solution to this problem but it is a very useful widget.

        cheers

        tachyon

      thanks everyone
Re: reg ex help
by Roy Johnson (Monsignor) on Apr 15, 2004 at 14:12 UTC
Re: reg ex help
by perlinux (Deacon) on Apr 16, 2004 at 09:41 UTC
    I think it's possible something like this:
    .... if(/^\d{4}: (\w\w ){13}(\w\w)(.*)$/) { # $_ of course my $number14 = $2; ....... }
      actually is it possible to do the regex in one line? Then it would be possible to put it into:
      $session->expect(30, '-re', qr'REGEX');