使用 Tcl switch 命令时必须进行额外的评估。下面是 repl 的一个示例 session ,用于说明我的意思:
$ tclsh
% regexp {^\s*foo} " foo"
1
% regexp {^\\s*foo} " foo"
0
% switch -regexp " foo" {^\\s*foo {puts "match"}}
match
% switch -regexp " foo" {{^\s*foo} {puts "match"}}
match
...第一个“switch”版本中需要添加一个额外的反斜杠。这在 Windows 上的 8.5.0 和 8.6.0 之间是一致的。有人可以向我指出手册中描述这种额外级别的取消引用实例和类似实例的部分吗?我的第一个想法是第一个“switch”版本中的大括号会保护反斜杠,但“switch”本身必须对模式应用额外级别的反斜杠替换。除非我误解了其他事物的细微差别。
编辑: ...嗯...就像 Johannes Kuhn 在下面所说的那样,反斜杠替换显然取决于使用的动态上下文,而不是创建的词汇上下文...
% set t {\s*foo}
\s*foo
% proc test_s x {set x}
% test_s $t
\s*foo
% proc test_l x {lindex $x 0}
% test_l $t
s*foo
% puts $t
^\s*foo
...这似乎是一个非常有趣的设计选择。
最佳答案
您在此处描述的问题很容易解决:
switch
和 regexp
之间的区别在于 switch 实际上采用一个列表。
因此,如果我们打印列表的第一个元素 {^\s*foo {puts "match"}}
with
% puts [lindex {^\s*foo {puts "match"}} 0]
^s*foo
这会导致我们不想要的结果。
列表构造是 little bit complex ,如果您不确定,请使用交互式 Tcl shell,它会通过 list
为您构建一个 shell。
编辑:确实,这是一个有趣的设计选择,但这适用于 Tcl 中的所有内容。例如,expr
使用专为算术表达式设计的迷你语言。由命令决定如何处理它的参数。即使像 if
、for
、while
这样的语言结构也只是将参数之一视为表达式,将其他参数视为脚本的命令。这种设计使得创建新的控制结构成为可能,例如 sqlite 的 eval,它采用 SQL 语句和应该对每个结果进行评估的脚本。
关于regex - Tcl switch 语句和 -regexp 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18747021/