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