我一直想知道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实际上是如何工作的,否则我不确定我做错了什么.也许有一个标志可以解决它我不知道的问题?
我不确定有一天我会真正使用这种代码,但我想学习它的工作方式可能会在其他方面帮助我.我希望我没有错过任何东西.如果您需要更多信息,请与我们联系!
这里的关键在于你的-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)