Home > database >  How to use regexp from matching against a list in tcl
How to use regexp from matching against a list in tcl

Time:06-09

I am new to TCL world and i was using regexp in my code. I am reading a file and printing the lines which are not in a list. Could please help me with them. I was trying the below code but it is not working.

        set fp [open file r]
        set pattern {pattern1 pattern2 pattern3...patternN}
        while {[gets $fp line] >= 0 } {
                   if {![regexp -- "$pattern" $line] } {
                    puts $line
                  }
         }

Thanks

CodePudding user response:

Your problem statement says that you are looking to print lines not in a list.

If that's really what you need, then you shouldn't use regexp, but should use ni which means "not in":

set fp [open file r]
set pattern {pattern1 pattern2 pattern3...patternN}
while {[gets $fp line] >= 0 } {
   if {$line ni $pattern} {
      puts $line
   }
}

If this is not what you need, then you'll need to define your regex as several patterns alternating with the | character. For example:

tclsh> regexp {ab xy} "ab"
0
tclsh> regexp {ab|xy} "ab"
1
set fp [open file r]
set pattern {pattern1|pattern2|pattern3|...|patternN}
while {[gets $fp line] >= 0 } {
   if {![regexp -- $pattern $line]} {
      puts $line
   }
}

Another option would be to continue defining $pattern as a list of patterns, but then you'd need to iterate through all the patterns and print the line if all the patterns failed to match.

set fp [open file r]
set pattern {pattern1 pattern2 pattern3 ... patternN}
while {[gets $fp line] >= 0 } {
   set match 0
   foreach p $pattern {
       if {[regexp -- $p $line]} {
           set match 1
           break
        }
   }
   if {$match == 0} {
       puts $line
   }

}

CodePudding user response:

While I like @ChrisHeithoff's answer, I think it is clearer when you use a helper procedure:

proc anyPatternMatches {patternList stringToCheck} {
    foreach pattern $patternList {
        if {[regexp -- $pattern $stringToCheck]} {
            return true
        }
    }
    return false
}

set fp [open file r]
set patterns {pattern1 pattern2 pattern3 ... patternN}
while {[gets $fp line] >= 0 } {
   if {![anyPatternMatches $patterns $line]} {
       puts $line
   }
}
  • Related