2016-06-13 995 views
0

如何解析tcl中的反斜杠字符?解析tcl中的反斜杠()字符

我有模式的值“\Q[9]_i_1_n_0”,我想找到包含此模式的行$line?我怎么能这样做?

puts $pattern回报:{\Q[9]_i_1_n_0},但我用foreach j [split $pattern]循环,因此$j纯属\Q[9]_i_1_n_0

regexp $pattern $pattern 

不起作用:

Error: couldn't compile regular expression pattern: invalid escape \ sequence 

lsearch $pattern $pattern返回-1

string match $pattern $pattern返回0 。

regexp {$pattern} $pattern返回0

+0

你试过双反斜杠吗?\\\'? –

+0

http://stackoverflow.com/questions/19495405/tcl-backslash-issue-regsub –

回答

0
set pattern {\Q[9]_i_1_n_0} 

string first $pattern $pattern 
# => 0 

匹配与string first两个字符串的文本内容进行比较,而不给予任何特殊含义的字符。 0的结果意味着在位置0处找到匹配(如果没有匹配,则得到-1)。 string first不会告诉你,如果你找到了一个完全匹配:因为你需要确定结果是0和字符串的长度是相同的。

通过“glob-style”/“字符串匹配”或正则表达式进行匹配需要考虑那些匹配语言特殊的字符。例如,\*?[]在全局样式匹配特殊,和\.*+?{}()^$在正则表达式匹配特殊。这里的“特殊”是指例如\并不意味着“反斜杠”,而是(在两种情况下)“逃逸”,即一个带走另一个角色的“特殊性”的角色。这意味着例如\\确实意味着反斜杠,并且\*确实意味着星号。

由于您使用的模式中包含的模式,可用于全局样式或正则表达式匹配前两个\[],他们需要进行转义。 (事实上​​,通过语法怪癖,一个]封闭转义[不需要进行转义。)

一个逃脱这些字符的最简单的方法是通过使用由string map命令执行的字符串翻译操作。有人会认为,这将这样的伎俩:

string map {\ \\ [ \[} $pattern ;# error! this code won't work! 

但不会工作,因为反斜杠仍处于string map命令特殊。我们需要在地图反斜线的数量就会翻一番:

string map {\\ \\\\ [ \\[} $pattern 

,现在我们可以尝试使用通配符式样/正则表达式匹配:

string match [string map {\\ \\\\ [ \\[} $pattern] $pattern 
# => 1 
regexp [string map {\\ \\\\ [ \\[} $pattern] $pattern 
# => 1 

1的结果意味着布尔真理:一个比赛被发现。需要注意的是,如果有一个前缀和/或后缀的结果会有所不同:

string match [string map {\\ \\\\ [ \\[} $pattern] abc${pattern}def 
# => 0 
regexp [string map {\\ \\\\ [ \\[} $pattern] abc${pattern}def 
# => 1 

这是因为该字符串匹配的模式的两端隐含固定,而正则表达式需要显式地锚,否则将忽略前面或后面的文本。

匹配在一个列表中是类似的。 lsearch -exact的作品类似string first,只不过它只接受完全相同的字符串。 lsearch -regexplsearch -glob分别像正则表达式和全局样式匹配一样工作。

set list [concat abc $pattern def] 
# => abc \Q[9]_i_1_n_0 def 
lsearch -exact $list [join $pattern] 
# => 1 
lsearch -regexp $list [string map {\\ \\\\ [ \\[} [join $pattern]] 
# => 1 
lsearch -glob $list [string map {\\ \\\\ [ \\[} [join $pattern]] 
# => 1 

这里1的结果表示列表中的第二个元素(索引1)与模式匹配。

(利用的concatjoin是有点低级别欺骗的,以避免在字符串表示在大括号中的方式获得。)

文档:concatjoinlsearchSyntax of Tcl regular expressionsregexpstring

+0

@ user2921643:我搞砸了一些列表项目的匹配。我已经更新了答案。 –

0

你已经有一个字符串,其中有几个字符,它们都是regexpstring match的元字符。特别是,默认情况下,两个解释反斜杠和括号都表示事物。这意味着lsearch找不到它(或lsearch -glob),lsearch -regexp将不起作用(无效的RE),并且lsearch -exact只会在整个字符串中找到它(与该lsearch选项不完全匹配的点)。

但你可以通过把***=在图案的正面覆盖的regexp风格匹配的行为,提供你正在寻找一个文字:

set sampleText {this is a sample \Q[9]_i_1_n_0 with the pattern in it} 
set pattern {\Q[9]_i_1_n_0} 
puts [regexp ***=$pattern $sampleText] 
# Prints 1... it matched! 

让我们得到一些更好的匹配信息:

puts [regexp -inline -indices ***=$pattern $sampleText] 
# {17 29} 

看起来像是对我来说。这也适用于lsearch -regexp; ***=技巧是RE引擎核心(共享)的一个特性。