使用字符串匹配时,是否需要转义特殊字符?

时间:2012-02-07 16:19:05

标签: escaping tcl

我正在编写一个脚本,使用tcl从SOAP消息中解析某个错误代码,我终于来到了将消息与所需消息进行比较的部分。如您所见,我正在尝试检查字符串“9000”是否包含在数组元素“$ soap(Fault)”中


if { [ string match *\<FaultCode\>9000\</FaultCode\>* $soap(Fault) ] } {

    # -- Success case

} else {

    # -- fail case

}

在我提供的示例中,我已经转义了tcl中的所有“特殊字符”:

&;`'"|*?~<>^()[]{}$\

但它是必需的吗?可以简单地做:

*<FaultCode>9000</FaultCode>*  ?

我已经彻底地环顾四周,并且找不到像我要求的那样精确的东西。我打算在tcl聊天室询问,但我找不到一个!

由于

4 个答案:

答案 0 :(得分:4)

简短的回答是,不,你不需要逃避所有这些角色。事实上,其中一些角色甚至都不特别。

这里有两层:首先,在tcl解析级别:通过tcl's parsing rules阅读,你有几个选择:

  • 用双引号括起你的论点。 (但是你必须担心嵌入式引号,[命令]和$变量)
  • 用括号包裹你的论点。 (但你必须担心嵌套大括号)
  • 使用上面的单词(但是你必须担心领先括号,引号,空格以及上面双引号的所有内容。)

所有这一切只是确定传递给[字符串匹配]的内容 - 第二层涉及[字符串匹配]如何处理此模式(它不是正则表达式,顺便说一下,它只是glob-style pattern) 。 tcl的glob样式模式中只有这些特殊字符:*,?,[] ,.如果您希望将其中任何一个视为文字,则必须将它们转义。其他任何内容都被视为字面匹配,因此您不必担心&lt;&gt;或/.

所以,这条线很好:

string match *<FaultCode>9000</FaultCode>* $soap(Fault)

但你也可以使用这些风格来风格化地设置匹配模式。

string match "*<FaultCode>9000</FaultCode>*" $soap(Fault)
string match {*<FaultCode>9000</FaultCode>*} $soap(Fault)

答案 1 :(得分:2)

对于string match,唯一的特殊字符是 [ \ * - - http://www.tcl.tk/man/tcl8.5/TclCmd/string.htm#M40

对于Tcl解析器一般来说,是的还有一些你需要考虑的事情 - http://www.tcl.tk/man/tcl8.5/TclCmd/Tcl.htm

答案 2 :(得分:1)

另一种(更简单的IMO)方法是只搜索字符串中是否存在给定的子字符串,并查看搜索是否成功,如下所示:

set found [expr {[string first $needle $haystack] >= 0}]

这只是一个简单的搜索,没有任何字符串被解释,所以不用担心转义。

换句话说,您的特殊需求太简单了,不能扔掉用于更重的提升的工具。例如,你需要使用正则表达式或全局匹配,如果你需要搜索“一个以<FaultCode>开头的子字符串,然后包含一组在'0'范围内的相邻字符 - '9 '并以</FaultCode>结尾 - 这就是它,特别是使用正则表达式引擎,允许您从字符串中提取数字字符的不确定子字符串。

此外,我觉得我应该在这样的情况下强制说明:用XML工具解析XML并不明智。特别是tclsoaptdom

答案 3 :(得分:0)

免责声明:我不知道TCL,只是正则表达式

Apparently,在TCL中,建议用双引号"regex"或大括号{regex}包围你的正则表达式 - 然后你不必担心逃避任何不是正则表达式的东西保留字符。

我非常确定<>不需要转义。

我不知道*可以用作周围的项目 - 这是一个保留的正则表达式字符。 鉴于此,我建议改为:{<FaultCode>9000</FaultCode>}