我在 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\\|__\\|__\\|"之前处理过之后的表达式。