Regex Pattern to Match, Excluding when… / Except between

前端 未结 6 875
别跟我提以往
别跟我提以往 2020-11-21 05:07

--Edit-- The current answers have some useful ideas but I want something more complete that I can 100% understand and reuse; that\'s why I set a bounty. Als

6条回答
  •  广开言路
    2020-11-21 05:14

    Hans if you don't mind I used your neighbor's washing machine called perl :)

    Edited: Below a pseudo code:

      loop through input
      if line contains 'if(' set skip=true
            if skip= true do nothing
            else
               if line match '\b\d{5}\b' set s0=true
               if line does not match s1 condition  set s1=true
               if line does not match s2 condition  set s2=true
               if s0,s1,s2 are true print line 
      if line contains '//endif' set skip=false
    

    Given the file input.txt:

    tiago@dell:~$ cat input.txt 
    this is a text
    it should match 12345
    if(
    it should not match 12345
    //endif 
    it should match 12345
    it should not match 12345.
    it should not match ( blabla 12345  blablabla )
    it should not match ( 12345 )
    it should match 12345
    

    And the script validator.pl:

    tiago@dell:~$ cat validator.pl 
    #! /usr/bin/perl
    use warnings;
    use strict;
    use Data::Dumper;
    
    sub validate_s0 {
        my $line = $_[0];
        if ( $line =~ \d{5/ ){
            return "true";
        }
        return "false";
    }
    
    sub validate_s1 {
        my $line = $_[0];
        if ( $line =~ /\.$/ ){
            return "false";
        }
        return "true";
    }
    
    sub validate_s2 {
        my $line = $_[0];
        if ( $line =~ /.*?\(.*\d{5.*?\).*/ ){
            return "false";
        }
        return "true";
    }
    
    my $skip = "false";
    while (<>){
        my $line = $_; 
    
        if( $line =~ /if\(/ ){
           $skip = "true";  
        }
    
        if ( $skip eq "false" ) {
            my $s0_status = validate_s0 "$line"; 
            my $s1_status = validate_s1 "$line";
            my $s2_status = validate_s2 "$line";
    
            if ( $s0_status eq "true"){
                if ( $s1_status eq "true"){
                    if ( $s2_status eq "true"){
                        print "$line";
                    }
                }
            }
        } 
    
        if ( $line =~ /\/\/endif/) {
            $skip="false";
        }
    }
    

    Execution:

    tiago@dell:~$ cat input.txt | perl validator.pl 
    it should match 12345
    it should match 12345
    it should match 12345
    

提交回复
热议问题