案例匹配正则表达式

Jer*_*rry 2 regex tcl

我一直想知道Tcl中的正则表达式匹配模式已经有一段时间了,我仍然难以理解它是如何工作的.我顺便使用Wish和Tcl/Tk 8.5.

MmmasidhmMm存储了一个随机字符串,$line我的代码是:

while {[regexp -all {[Mm]} $line match]} {
    puts $data $match
    regsub {[Mm]} $line "" line
}
Run Code Online (Sandbox Code Playgroud)

$data 是一个文本文件.

这就是我得到的:

m
m
m
m
m
m
Run Code Online (Sandbox Code Playgroud)

虽然我在期待:

M
m
m
m
M
m
Run Code Online (Sandbox Code Playgroud)

我正在尝试一些事情,看看当我得到这个时,改变一点会影响结果:

while {[regexp -all {^[Mm]} $line match]} {
    puts $data $match
    regsub {[Mm]} $line "" line
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

M
m
m
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,$match保持这种情况.

我想知道为什么在第一种情况下,$match由于某种原因自动变为小写.除非我不理解regexp实际上是如何工作的,否则我不确定我做错了什么.也许有一个标志可以解决它我不知道的问题?

我不确定有一天我会真正使用这种代码,但我想学习它的工作方式可能会在其他方面帮助我.我希望我没有错过任何东西.如果您需要更多信息,请与我们联系!

Hai*_* Vu 5

这里的关键在于你的-all旗帜.该文件说:

-all - 使正则表达式在字符串中尽可能多地匹配,返回找到的匹配总数.如果使用匹配变量指定,则它们将仅包含最后一个匹配的信息.

这意味着变量匹配包含最后一个匹配,这是一个小写的"m".放下-all旗帜,你会得到你想要的.

更新

如果您的目标是删除所有'm'而不管大小写,那么整个代码块可以压缩成一行:

regsub -all {[MM]} $line "" line
Run Code Online (Sandbox Code Playgroud)

或者,更直观地说:

set line [string map -nocase {m ""} $line]; # Map all M's into nothing
Run Code Online (Sandbox Code Playgroud)