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

If have this perl script for reading the uptime of a device and then take out the beginning stuff. I was helped originally by some kind monk originally.
#! /usr/pkg/bin/perl open(TIME, "snmpget 192.168.100.1 public system.sysUpTime.0 |"); $line = <TIME>; chop $line; if ($line =~ m|^.+')'[\s\t]+(\w+),[\s\t]+(\w)$|) { print "$1, $2\n"; } close(TIME);
Now I have moved to 5.8.0 and I get the error :-
Unmatched ) in regex; marked by <-- HERE in m/^.+') <-- HERE '[\s\t]+( +\w+),[\s\t]+(\w)$/ at ./uptime line 12.
So, I can understand what this thing is doing, it is looking for the last ) and giving me the stuff after it, minus a space or two. I am a c++ and a PHP coder so I see that it is not seeing the ) used in the exp as an item in the string BUT why does it work on a 5.6.0 system!!!!! so they made a change, I tried to add a \ before it, that stops the error but the function then fails. I have also tried changing the ' marks to " marks. With the \ inplace it failes, I outputted the result to make sure that was right first and it is, here is the base.
SNMPv2-MIB::sysUpTime.0 = Timeticks: (2137215391) 247 days, 8:42:33.91
I need everything after the ) !!!!! hopefully someone has a quick answer for me!

Replies are listed 'Best First'.
Re: 5.6.0 change on 5.8.0 - ahhh!
by tachyon (Chancellor) on Dec 24, 2003 at 02:35 UTC

    split is all you need.

    my $str = "SNMPv2-MIB::sysUpTime.0 = Timeticks: (2137215391) 247 days, + 8:42:33.91\n"; my @bits = split ' ', $str; print "\$bits[$_] = '$bits[$_]'\n" for 0..$#bits; print join ' ', 'Split:', @bits[4..6], "\n"; # alternatively fixing the RE .... print "RE: $1 | $2\n" if $str =~ m|\)\s+(\d[\w ]+),\s+([0-9:\.]+)$|; __DATA__ $bits[0] = 'SNMPv2-MIB::sysUpTime.0' $bits[1] = '=' $bits[2] = 'Timeticks:' $bits[3] = '(2137215391)' $bits[4] = '247' $bits[5] = 'days,' $bits[6] = '8:42:33.91' Split: 247 days, 8:42:33.91 RE: 247 days | 8:42:33.91

    cheers

    tachyon

Re: 5.6.0 change on 5.8.0 - ahhh!
by tachyon (Chancellor) on Dec 24, 2003 at 03:01 UTC

    As a side note I don't see how that regex could EVER have worked on any perl ever.

    C:\>perl -MYAPE::Regex::Explain -e "print YAPE::Regex::Explain->new(qr +|^.+')'[\s\t]+(\ w+),[\s\t]+(\w)$|)->explain" Unmatched ) before HERE mark in regex m/^.+') << HERE '[\s\t]+(\w+),[\ +s\t]+(\w)$ / at -e line 1. C:\>perl -MYAPE::Regex::Explain -e "print YAPE::Regex::Explain->new(qr +|^.+'\) s\t]+(\w+),[\s\t]+(\w)$|)->explain" The regular expression: (?-imsx:^.+'\)'[\s\t]+(\w+),[\s\t]+(\w)$) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- ^ the beginning of the string ---------------------------------------------------------------------- .+ any character except \n (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ' '\'' ---------------------------------------------------------------------- \) ')' ---------------------------------------------------------------------- ' '\'' ---------------------------------------------------------------------- [\s\t]+ any character of: whitespace (\n, \r, \t, \f, and " "), '\t' (tab) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ( group and capture to \1: ---------------------------------------------------------------------- \w+ word characters (a-z, A-Z, 0-9, _) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ) end of \1 ---------------------------------------------------------------------- , ',' ---------------------------------------------------------------------- [\s\t]+ any character of: whitespace (\n, \r, \t, \f, and " "), '\t' (tab) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ( group and capture to \2: ---------------------------------------------------------------------- \w word characters (a-z, A-Z, 0-9, _) ---------------------------------------------------------------------- ) end of \2 ---------------------------------------------------------------------- $ before an optional \n, and the end of the string ---------------------------------------------------------------------- ) end of grouping ---------------------------------------------------------------------- C:\>perl -v This is perl, v5.6.1 built for MSWin32-x86-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2001, Larry Wall Binary build 635 provided by ActiveState Corp. http://www.ActiveState. +com Built 15:34:21 Feb 4 2003 Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using `man perl' or `perldoc perl'. If you have access to + the Internet, point your browser at http://www.perl.com/, the Perl Home Pa +ge. C:\>

    Not only does it not compile under 5.6.1 but if you add the required escape on the ) ie \) you can see that it is looking for literally ')' ie single quote RT bracket single quote (does not exist) and at the end of the string it is only matching \w+ which are the chars A-Za-z0-9_ inclusive which will NEVER match 8:42:33.91 due to the fact that there are colons and . chars there too......

    Note that \s matches ' ' \t \r \n so \s\t is unnecessary just \s is all that is required.

    cheers

    tachyon

      I swear to you it works on my netbsd box running perl 5.6.0 but your way is better, thanks a lot. and the quick reply too.