in reply to Re^3: String Matching
in thread String Matching

Sorry Dave, Spoke too soon

My test box is Linux and it works fine there but the target system is Solaris and only has Perl 5.8.4

I get errors there as follows

Unrecognized escape \S passed through at ./syslog_smtp.pl line 36. Unrecognized escape \s passed through at ./syslog_smtp.pl line 36. Unrecognized escape \s passed through at ./syslog_smtp.pl line 36.

Line 36 reads

my ( $from, $srvrip ) = $remainder =~ m/<=\s*(\S+)[^[]+\[([^\]]+);

Replies are listed 'Best First'.
Re^5: String Matching
by AnomalousMonk (Archbishop) on Aug 14, 2012 at 16:41 UTC
    my ( $from, $srvrip ) = $remainder =~ m/<=\s*(\S+)[^[]+\[([^\]]+);

    If that's not just a cut-and-paste tyop (no terminating / for the m//), then your Perl implementation is seriously deficient since Perl has had the  \S character class (complement of \s) since 4.? at least (to the best of my recollection).

    Update: I just noticed that the Solaris Perl 5.8.4 compiler is complaining about both  \S and  \s (big-S and little-s) classes. Well, the comment still applies.

Re^5: String Matching
by davido (Cardinal) on Aug 14, 2012 at 16:41 UTC

    Your regular expression deserves a '/' at the end of it. Aside from that I don't see anything that wouldn't be compatible with v5.8.x. \s and \S have been around for a long time. Is this really pasted from your real code? Please paste from your real code.


    Dave

      Below is the full code. The odd thing is its running on my ubuntu box - I am sure there is a syntax error I am blind to here but then why is no problem reported under ubuntu

      steveb@laptop:~/Loading_Scripts$ perl -c syslog_smtp.pl syslog_smtp.pl syntax OK

      On the Solaris box

      bash-3.00# perl -c ./syslog_smtp.pl Unrecognized escape \S passed through at ./syslog_smtp.pl line 38. Unrecognized escape \s passed through at ./syslog_smtp.pl line 38. Unrecognized escape \s passed through at ./syslog_smtp.pl line 38. "my" variable $msgdate masks earlier declaration in same scope at ./sy +slog_smtp.pl line 53. "my" variable $msgtime masks earlier declaration in same scope at ./sy +slog_smtp.pl line 53. "my" variable $msgid masks earlier declaration in same scope at ./sysl +og_smtp.pl line 53. "my" variable $from masks earlier declaration in same scope at ./syslo +g_smtp.pl line 62. "my" variable $remainder masks earlier declaration in same scope at ./ +syslog_smtp.pl line 62. "my" variable $msgdate masks earlier declaration in same scope at ./sy +slog_smtp.pl line 63. "my" variable $msgtime masks earlier declaration in same scope at ./sy +slog_smtp.pl line 63. "my" variable $msgid masks earlier declaration in same scope at ./sysl +og_smtp.pl line 63. "my" variable $remainder1 masks earlier declaration in same scope at . +/syslog_smtp.pl line 63. "my" variable $csv masks earlier declaration in same scope at ./syslog +_smtp.pl line 66. Global symbol "$remainder1" requires explicit package name at ./syslog +_smtp.pl line 38. Global symbol "$csv" requires explicit package name at ./syslog_smtp.p +l line 38. Global symbol "$csv" requires explicit package name at ./syslog_smtp.p +l line 38. syntax error at ./syslog_smtp.pl line 52, near "my ( $from, $srvrip ) += $remainder =~ m/=>\s*(" (Might be a runaway multi-line ** string starting on line 38) syntax error at ./syslog_smtp.pl line 60, near "} elsif" syntax error at ./syslog_smtp.pl line 70, near "}" ./syslog_smtp.pl had compilation errors.
      #!/usr/bin/perl # use strict; use warnings; my $no = 0; my %monthNos = map {$_ => ++$no} qw{ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov +Dec }; while (my $line = <STDIN>) { chomp($line); my ($mon, $day, $time, $loghost, $prog, $remainder) = split m{:?\s+}, $line, 6; my ($user) = $remainder =~ m{user=([^,]+)}; my ($rip) = $remainder =~ m{rip=([^,]+)}; my ($op) = $remainder =~ m{\s(==|<=|\*\*|\+\+)\s}; my $yr = 2012; my $srvrip = ''; my $from = ''; my $msgid = ''; my $msgdate = ''; my $msgtime = ''; $remainder =~ tr/"/'/; $_ //= '' for $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, +$msgtime; # <= message arrival # => normal message delivery # -> additional address in same delivery # *> delivery suppressed by -N # ** delivery failed; address bounced # == delivery deferred; temporary problem if( $op eq '<=' ){ # message arrival my ( $from, $srvrip ) = $remainder =~ m/<=\s*(\S+)[^[]+\[([^\]]+)/ +; # <=\s* # (\S+) # Capture the email address following <= # [^[]+\[ # Skip to the first subsequent square bracket. # ([^\]]+) # Capture until a closing bracket. # /x; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SVRIP, + ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,%s,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $srvrip, $msgid, $remainder; print "$csv\n"; } elsif( $op eq '=>' ){ # normal message delivery my ( $from, $srvrip ) = $remainder =~ m/=>\s*(\S+)[^[]+\[([^\]]+)/ +; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SVRIP, + ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,%s,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $srvrip, $msgid, $remainder; print "$csv\n"; } elsif( $op eq '==' ){ # delivery deferred; temporary problem my ( $from ) = $remainder =~ m/==\s*(\S+)/; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SRVRIP +, ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $msgid, $remainder; print "$csv\n"; } elsif( $op eq '**' ){ # fall back on a default behavior my ( $from ) = $remainder =~ m/\*\*\s*(\S+)/; my ($msgdate, $msgtime, $msgid, $remainder1) = split m{:?\s+}, $remainder, 4; # DATETIME, SERVER, SEQNO, DATETIME1, MSGID, SENDER, RECIPIENT, SRVRIP +, ORIGMSGID, STATUS, SUBJECT my $csv = sprintf q{%02d-%02d-%s %s,%s,,%s %s,%s,%s,,,%s,,"%s"}, $yr, $monthNos{$mon}, $day, $time, $loghost, $msgdate, $msgtime, $ +msgid, $from, $msgid, $remainder; print "$csv\n"; } else { my $csv = sprintf q{%02d-%02d-%s %s,%s,,,,,,,,,"%s"}, $day, $monthNos{ $mon }, $yr, $time, $loghost, $remainder; print "$csv\n"; } }

        On line 26 you have the following:

        $_ //= '' for $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, $msg +time;

        The //= operator was introduced in 5.10.0. As you mentioned, you're running this on a 5.8.x version of Perl. That's giving the compiler fits. Change that line to:

        $_ = defined ? $_ : '' for $user, $rip, $op, $srvrip, $from, $msgid, $ +msgdate, $msgtime;

        Or maybe a little more clarity:

        use constant EMPTY_STRING => q{}; # ..... foreach ( $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, $msgtime + ) { $_ = EMPTY_STRING # Alias propagates to foreach list. if not defined $_; }

        Dave

        $_ //= '' for $user, $rip, $op, $srvrip, $from, $msgid, $msgdate, $msg +time; ### line 25

        A big problem here is that the  //= operator (and its pal  // 'defined-or') were not added until version 5.10 (AFAIR), so 5.8.4 is definitely not going to grok this. Try
            defined($_) || $_ = '' for ...;
        instead.