【发布时间】:2012-06-27 04:29:55
【问题描述】:
关于 TCL 中的正则表达式,如果我使用以下正则表达式:
regexp "helloworld\[\\s]+.name."
匹配以下输出:
helloworld (name)
它有效。但我想知道是否需要在“]”前面添加“\”,我看到一些其他人制作的代码,他们没有用“\”关闭“]”,我想要知道为什么。
【问题讨论】:
关于 TCL 中的正则表达式,如果我使用以下正则表达式:
regexp "helloworld\[\\s]+.name."
匹配以下输出:
helloworld (name)
它有效。但我想知道是否需要在“]”前面添加“\”,我看到一些其他人制作的代码,他们没有用“\”关闭“]”,我想要知道为什么。
【问题讨论】:
一个原因可能是 Utkanos 解释的,另一个可能是由于 Tcl 特定的行为:[ 字符在允许命令替换的地方具有特殊含义。观察:
% proc foo {} { return y }
% puts x[foo]z
xyz
因此,当您在 Tcl 中使用正则表达式时(通过尝试按字面意思指定它,或在运行时构造等),您必须考虑形成此正则表达式的字符串将如何被 Tcl 处理。
这就是为什么大多数时候你会看到正则表达式的字符直接传递给使用花括号 { 和 } 分组的 regexp 命令:它抑制(大部分)Tcl 的替换,因此允许“按原样”编写正则表达式规范,几乎使用其简单的语法,没有任何转义。
但这显然不适用于您想要动态构建规范的情况(例如,将变量的内容嵌入其中)。通常人们使用双引号对正则表达式字符进行分组,因此需要进行特殊的转义以防止某些 Tcl 的替换。更简洁的方法可能是使用 append 命令构建模式。
至于在 Internet 上查找这本书,"Mastering Regular Expressions" 是通常认为该主题的书。
作为旁注,在您的特定示例中,根本不需要方括号:在正则表达式中,它们用于创建“字符范围” - 匹配指定范围之外的单个字符的模式,并且在您的如果该范围仅包含一个(元)字符,该字符被定义为匹配输入中的单个空白字符。所以在这种特殊情况下,模式helloworld\s+.name. 就可以了。
【讨论】:
regexp {helloworld\s+.name.} $someString,在{大括号}字符中使用(大部分)简单的正则表达式。
] 没有被转义:它对解析器没有特殊意义,因为当时解析器在解析由双引号分组的字符串时会看到这个右括号它还没有看到任何打开的[,因此没有嵌套组需要完成和处理。如果您觉得] 更具可读性,您仍然可以避开它——它不会混淆解析器。
不,因为您使用 [ 具有特殊含义,即定义范围。仅当您想匹配文字 [ 时,您才可以使用反斜杠对其进行转义。反斜杠用于转义字符,否则会在 REGEXP 中调用特殊行为。
(Javascript)
var str = "[hello]";
str.match(/[a-z]+/); //resultant array: ['hello']
str.match(/\[[a-z]+\]/); //resultant array: ['[hello]']
【讨论】:
我相信这个表达是你想要的:
regexp {helloworld\s+.name.} $the_string
你根本不需要任何方括号。
【讨论】: