2

I have been wondering about a regexp matching pattern in Tcl for some time and I've remained stumped as to how it was working. I'm using Wish and Tcl/Tk 8.5 by the way.

I have a random string MmmasidhmMm stored in $line and the code I have is:

while {[regexp -all {[Mm]} $line match]} {
    puts $data $match
    regsub {[Mm]} $line "" line
}

$data is a text file.

This is what I got:

m
m
m
m
m
m

While I was expecting:

M
m
m
m
M
m

I was trying some things to see how changing a bit would affect the results when I got this:

while {[regexp -all {^[Mm]} $line match]} {
    puts $data $match
    regsub {[Mm]} $line "" line
}

I get:

M
m
m

Surprisingly, $match keeps the case.

I was wondering why in the first case, $match automatically becomes lowercase for some reason. Unless I am not understanding how the regexp actually is working, I'm not sure what I could be doing wrong. Maybe there's a flag that fixes it that I don't know about?

I'm not sure I'll really use this kind of code some day, but I guess learning how it works might help me in other ways. I hope I didn't miss anything in there. Let me know if you need more information!

Jerry
  • 70,495
  • 13
  • 100
  • 144

1 Answers1

5

The key here is in your -all flag. The documentation for that said:

-all -- Causes the regular expression to be matched as many times as possible in the string, returning the total number of matches found. If this is specified with match variables, they will contain information for the last match only.

That means the variable match contains the very last match, which is a lower case 'm'. Drop the -all flag and you will get what you want.

Update

If your goal is to remove all 'm' regardless of case, that whole block of code can be condensed into just one line:

regsub -all {[MM]} $line "" line

Or, more intuitively:

set line [string map -nocase {m ""} $line]; # Map all M's into nothing
Hai Vu
  • 37,849
  • 11
  • 66
  • 93
  • Ah, I should have looked into the exact definition of `-all`. And to test it, I remove `-all` and it works as intended. Thanks for the pointers! – Jerry Mar 29 '13 at 15:34