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

Ok I have read previous deiscussions on this and they did help :D However I have another type data to parse through. I am running through a Cisco router config and have managed to pull out the relevant section of the config I require, however the END point in the range operator expression I wish to leave out when returning the required part of the config.

Here is the extracted data:

policy-map CE-PE-ADCORP-EA-LM-RBA-INPUT
class ADCORP-EA-LM-INPUT-OUTPUT-PLATINUM
police cir 640000 bc 240000 be 480000
conform-action set-mpls-exp-transmit 4
exceed-action set-mpls-exp-transmit 3
violate-action drop
class ADCORP-EA-LM-RBA-INPUT-OUTPUT-GOLD
police cir 256000 bc 96000 be 192000
conform-action set-mpls-exp-transmit 2
exceed-action set-mpls-exp-transmit 1
violate-action drop
policy-map CE-PE-UBSW-PRIMARY-INPUT

This is the code I'm using in the match after reading in the router config file is:

$ouputpol = "CE-PE-ADCORP-EA-LM-RBA-INPUT"; if (/^ policy-map $ouputpol/.../ policy-map/) { print; }
Now I'm grabbing everything between and including the line starting with my policy-map I'm interested in until the next policy-map. Now I want to exclude the line "policy-map CE-PE-UBSW-PRIMARY-INPUT" in the output of my expression.

How do I go about this....I'm stumped......?? I'm sure it's simple but I'm just not seeing it.
Another question I have is how do I print all text between two html tags using the .. operator but exclude the tags themselves after reading in an html file?
Example:
plenty html up here <pre> a whole bunch of text here </pre> a whole lot more html here
If this is confusing let me know?

Replies are listed 'Best First'.
Re: Matching between START and END revisited
by bart (Canon) on Oct 18, 2003 at 11:02 UTC
    There are two approaches for this kind of question. Both involve examining the range operator a bit more closely.

    Option 1 is to catch the return value of the range operator itself, which you now only use as a boolean.

    if(my $cnt = /^ policy-map $ouputpol/ ... / policy-map/) {
    (Precedence of "..." is higher than the assignment.)

    If you examine the contents of $cnt closely, you'll see it's a counter, with the numerical value 1 for the first line, 2 for the next... and as a string, it has a "E0" appended only for the very last line. So you can check it:

    print unless $cnt==1 || $cnt =~ /E/;
    Note that that suffix doesn't change the value of the number, while it's still a valid representation of it.

    The second approach is to catch the return value of the left and right hand sides individually:

    if(($my $first = /^ policy-map $ouputpol/) ... (my $last = / policy-ma +p/)) {
    Note the extra parens. Here, $first will be true for the first line, and $last will be true for the last one. No additional check is necessary.
    print unless $first || $last;

    For the people who want a simple standalone test, without requiring something ressembling your data:

    for my $i (1 .. 15) { if(my $cnt = $i==5 ... $i==10) { print "$i - $cnt\n"; } }
    which prints:
    5 - 1
    6 - 2
    7 - 3
    8 - 4
    9 - 5
    10 - 6E0
    
    And the other one:
    for my $i (1 .. 15) { if((my $first = $i==5) ... (my $last = $i==10)) { # note: $first will be undefined for any but the first line be +cause of the 3 dots # and $last will be undefined for the first line local $^W; print "$i - $first / $last\n"; } }
    which prints:
    5 - 1 / 
    6 -  / 
    7 -  / 
    8 -  / 
    9 -  / 
    10 -  / 1
    
      Arrrrgggghhhhhh.....
      Thank you....thank you.....thank you
      Mental block of note...... this works perfectly....you have no idea how this is going to help me with converting an exisiting QoS model to an AVVID compliant one.
      Thanks to bart