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