我在TCL中有以下代码:
"\\*05.|__|##|.T|__|__|"
尝试匹配以下输出:
*05 |__|##| T|__|__|
并且匹配。
但如果输出为:
*05 |__|##|__|__|__|
它也匹配,问题是什么,以及如何修复它?
答案 0 :(得分:8)
字符|
是一个特殊字符,用于表示正则表达式中的“或”。你需要做的就是逃避它。
"\\*05.\\|__\\|##\\|.T\\|__\\|__\\|"
现在,为了避免所有这些双重转义,只需使用大括号!
regexp {\*05.\|__\|##\|.T\|__\|__\|} $string
如果您想要更深入的解释,您应该问过。我不咬人!的xD
使用时:
regexp "\\*05.|__|##|.T|__|__|" "*05 |__|##| T|__|__|"
Tcl正在调用命令regexp
并首先评估表达式(它在被带到实际命令regexp
之前首先被处理,并且发送给regexp
的是:
\*05.|__|##|.T|__|__|
现在,由于|
表示regexp
中的或,因此该命令会将其评估为:
一个文字字符*
,然后05
,然后是任何一个字符(换行符除外),或
两个_
,或
两个#
,或
后跟T
,或
两个_
,或
两个_
,或
没有
然后将上述每个字符与您要匹配的字符串*05 |__|##| T|__|__|
进行比较。
第1步:字符串中是否有*05.
?是的,“* 05”在字符串中,因此匹配,因此返回1.
当你将它与*05 |__|##|__|__|__|
进行比较时,会发生同样的事情:
第1步:字符串中是否有*05.
?是的,“* 05”在字符串中,因此匹配,因此返回1.
使用双重转义,在任何评估之后转到正则表达式的字符串是:
\*05.\|__\|##\|.T\|__\|__\|
然后regexp将其读作:
一个文字*
字符,然后05
,然后是任何字符,然后是文字|
,两个_
,文字|
,两个{{ 1}},文字#
,任何字符,|
,文字T
,两个|
,文字_
,两个{{1}和文字|
。
只有一个选项,因此当它与_
比较时,它会匹配。
如果将其与|
进行比较,当正则表达式检查*05 |__|##| T|__|__|
时,它将找不到匹配项。
大括号会阻止在将表达式发送到regexp过程之前对其进行求值。因此,表达式将与您输入的表达式保持一致。如果你把:
*05 |__|##|__|__|__|
正则表达式将收到T
并且解释为{\\*05.\\|__\\|##\\|.T\\|__\\|__\\|}
0次或更多次,然后是\\*05.\\|__\\|##\\|.T\\|__\\|__\\|
,然后是任何字符,\
,或等等。 ..
这就是为什么你不用双括号逃脱:
05
regexp将收到的表达式为\
,这是您之前处理{\*05.\|__\|##\|.T\|__\|__\|}
之后的表达式。