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

AARRRGH!! I've been at this regex for 4 hours, now. Can someone tell me why this doesn't work? The data:
SLOT 0 (RP/LC 0 ): Route Processor SLOT 2 (RP/LC 2 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 3 (RP/LC 3 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 4 (RP/LC 4 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 7 (RP/LC 7 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 16 (CSC 0 ): Clock Scheduler Card(8) SLOT 17 (CSC 1 ): Clock Scheduler Card(8) SLOT 18 (SFC 0 ): Switch Fabric Card(8) SLOT 19 (SFC 1 ): Switch Fabric Card(8) SLOT 20 (SFC 2 ): Switch Fabric Card(8) SLOT 24 (PS A1 ): DC Power Supply(8) SLOT 26 (PS B1 ): DC Power Supply(8)
I want to match all lines, EXCEPT those containing, "Clock", "Switch", "Power", " Processor". Here's the regex:
if ($rtr_diag =~ m/^(SLOT.*$)/ && ! /(Processor.*$)/|/(Switch.*$)/|/(Power.*$)/|/(Clock.*$)/ ) { do stuff}
What's going on, here??? I've tried [^...]; didn't work. Along with every other way, but the right way, apparently.

Replies are listed 'Best First'.
(jcwren) RE: THIS not THAT
by jcwren (Prior) on Oct 03, 2000 at 07:09 UTC
    #!/usr/local/bin/perl -w use strict; { while (<DATA>) { if (!/Clock|Switch|Power|Processor/) { print "Doing stuff with $_"; } } } __DATA__ SLOT 0 (RP/LC 0 ): Route Processor SLOT 2 (RP/LC 2 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 3 (RP/LC 3 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 4 (RP/LC 4 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 7 (RP/LC 7 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 16 (CSC 0 ): Clock Scheduler Card(8) SLOT 17 (CSC 1 ): Clock Scheduler Card(8) SLOT 18 (SFC 0 ): Switch Fabric Card(8) SLOT 19 (SFC 1 ): Switch Fabric Card(8) SLOT 20 (SFC 2 ): Switch Fabric Card(8) SLOT 24 (PS A1 ): DC Power Supply(8) SLOT 26 (PS B1 ): DC Power Supply(8)

    [jcw@linux fs]$ perl q.pl SLOT 2 (RP/LC 2 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 3 (RP/LC 3 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 4 (RP/LC 4 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode SLOT 7 (RP/LC 7 ): 1 Port Packet Over SONET OC-12c/STM-4c Single Mode [jcw@linux fs]$
    --Chris

    e-mail jcwren
Re: THIS not THAT
by chromatic (Archbishop) on Oct 03, 2000 at 08:28 UTC
    Heh, jcwren demonstrates the first virtue of a Perl programmer. Here's something closer to what you intend:

    print if /^SLOT/ && !(/Switch|Power|Clock|Processor/);

    In one regex (ugly and not optimized and with more question marks than is healthy:

    print if /^SLOT .*?: (?!(?:Clock|Switch|.*?Power|.*?Processor))/;

    I'd go with the first.

      This is what I came up with. Comments? Criticisms?
      foreach $rtr_diag(@diaglist) { next if ($rtr_diag =~ m/Clock|Switch|Power|Processor/); push @{$slots{$_}}, $rtr_diag; }
        This would almost certainly be faster:
        foreach (@diaglist) { next if /Clock/; next if /Switch/; next if /Power/; next if /Process +or/; push @something, $_; }
        The constant-text-only regex means that Boyer-Moore can kick in sooner, or so says the hints I read about regex a while back.

        -- Randal L. Schwartz, Perl hacker