【问题标题】:TCL: How to escape a single brace '{' in a string quoted using braces '{...}'?TCL:如何在使用大括号'{...}'引用的字符串中转义单个大括号'{'?
【发布时间】:2015-10-10 04:15:06
【问题描述】:

我正在尝试使用花括号来定义字符串{ } 而不是双引号" ",这样我就不必转义多个字符(例如$[、@ 987654325@)。

但是,当我的字符串需要在其中包含一个 { 时,我遇到了一些问题。
我知道我可以通过简单地使用双引号字符串并转义 { 来实现这一点,但是我将如何使用“花括号字符串”来做到这一点?

例如。 我想puts 将以下字符串 'proc foo { } {' 发送到标准输出。

puts "proc foo \{ \} \{" 给了我想要的输出:'proc foo { } {'

但是,puts { proc foo \{ \} \{ } 通过逐字打印反斜杠给我:'proc foo \{ \} \{'。

如果我跳过反斜杠 puts { proc foo { } {,它会抱怨缺少大括号。

另外,如果所需的字符串中有一个匹配的右大括号,它可以正常工作。
puts { proc foo { } { } } 给了我预期的:'proc foo { } { }'

在“花括号字符串”中转义单个不匹配的花括号的正确方法是什么?

【问题讨论】:

    标签: string tcl curly-braces quoting


    【解决方案1】:

    最好的解决方案是使用subst。其他结构可能有效,但不清楚或临时。 在你的例子中,写:

    set str {proc foo \{ \} \{}
    ==> proc foo \{ \} \{     # string is unchanged
    set str2 [subst $str]
    ==> proc foo { } {        # backslashes are replaced
    

    请注意,通过使用subst,'\n' 将被替换为文字行尾。改用 '\\n' 来保留 '\n'。

    如果字符串包含要保留的方括号或“$”字符,可以添加:-nocommands,或-novariables。例如:

    set str [subst -novar {proc foo \{ \} \{$var}]
    ==> proc foo { } {$var
    

    您可以在以下位置找到更多类似提示:https://ipenv.com/ins-and-outs-tcltk

    【讨论】:

      【解决方案2】:

      抱歉,大括号字符串的服务条款要求您为每个左大括号提供一个匹配的右大括号。拥有不匹配大括号的唯一方法是用反斜杠引用/转义它们,但不会执行反斜杠替换,因此反斜杠与单独的大括号一起进入字符串。

      这并不意味着你不能构造你想要的字符串,例如这样:

      set foo { proc foo { } }
      # ->  proc foo { } 
      append foo "{ "
      # ->  proc foo { } { 
      

      (顺便说一句,双引号字符串中的大括号不需要反斜杠," proc foo { } { " 就可以了。)

      但是,您正在构建的字符串似乎暗示您正在脚本中构建过程定义,并且以错误的方式进行。而不是像这样组装定义:

      set foo { proc foo { } }
      # ->  proc foo { } 
      append foo "{ "
      # ->  proc foo { } { 
      append foo { puts foo }
      # ->  proc foo { } {  puts foo 
      append foo " }"
      # ->  proc foo { } {  puts foo  }
      

      你应该这样做:

      set name foo
      set args {}
      set body {puts foo}
      proc $name $args $body
      

      直接定义过程。如果你需要它作为一个字符串,把它包起来:

      set foo [list proc $name $args $body]
      # -> proc foo {} {puts foo}
      

      是的,我正在使用list 来构造一个字符串。这是因为将proc $name $args $body 包裹在双引号中会导致命令的列表结构丢失。我创建了一个列表,然后将该列表的字符串表示形式用作字符串。

      如果你这样做,你是在使用 Tcl 解释规则并利用它们,而不是反对它们。这意味着更少的工作和更少的错误。

      文档:appendlistprocset

      【讨论】:

        猜你喜欢
        • 2011-08-09
        • 1970-01-01
        • 2018-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-20
        • 2022-11-18
        相关资源
        最近更新 更多