1

TCL に次のコードがあります。

"\\*05.|__|##|.T|__|__|"

次の出力と一致させようとしています:

*05 |__|##| T|__|__|

そしてそれは一致します。

ただし、出力が次の場合:

*05 |__|##|__|__|__|

それも一致しますが、何が問題で、どのように修正するのですか?

4

1 に答える 1

8

この文字|は特殊文字であり、正規表現で「または」を意味するために使用されます。あなたがする必要があるのは、それを逃れることです。

"\\*05.\\|__\\|##\\|.T\\|__\\|__\\|"

さて、これらすべての二重エスケープを避けるために、中括弧を使用してください!

regexp {\*05.\|__\|##\|.T\|__\|__\|} $string

説明

もっと詳しい説明が欲しければ、質問すべきでした。噛まない!xD

使用する場合:

regexp "\\*05.|__|##|.T|__|__|" "*05 |__|##| T|__|__|"

Tcl はコマンドを呼び出してregexpおり、式が最初に評価されます (実際のコマンドに取り込まれる前に最初に処理され、regexp送信先regexpは次のとおりです。

\*05.|__|##|.T|__|__|

ここで、orは inを|意味するので、コマンドはそれを次のように評価します。regexp

  • 1 つのリテラル文字*、次に05、任意の 1 文字 (改行を除く)、または

  • 2 _、または

  • 2 #、または

  • T, ORが後に続く任意の文字

  • 2 _、または

  • 2 _、または

  • なし

次に、上記のそれぞれを、一致させたい文字列 と比較します*05 |__|##| T|__|__|

ステップ 1:*05.文字列の中にありますか? はい、「*05」は文字列に含まれているため一致するため、1 が返されます。

と比較すると*05 |__|##|__|__|__|、同じことが起こります。

ステップ 1:*05.文字列の中にありますか? はい、「*05」は文字列に含まれているため一致するため、1 が返されます。


修正

二重エスケープでは、評価後に正規表現に移動する文字列は次のとおりです。

\*05.\|__\|##\|.T\|__\|__\|

正規表現はそれを次のように読み取ります。

1 つのリテラル*文字、05次に任意の文字、次にリテラル|、2 つ_、リテラル|、2 つ#、リテラル|、任意の文字、a T、リテラル|、2 つ_、リテラル|、2 _、およびリテラル|

選択肢は 1 つしかないため、 と比較する*05 |__|##| T|__|__|と一致します。

と比較すると*05 |__|##|__|__|__|、正規表現がチェックするTと、一致が見つかりません。


ブレースは何をしますか?

中括弧は、式が正規表現手続きに送られる前に評価されるのを防ぎます。したがって、式は入力したとおりのままです。あなたが置く場合:

{\\*05.\\|__\\|##\\|.T\\|__\\|__\\|}

正規表現は、 を0 回以上、次に、任意の文字、、OR などとして受け取り\\*05.\\|__\\|##\\|.T\\|__\\|__\\|、解釈します。\05\

これが、中かっこで二重エスケープしない理由です。

{\*05.\|__\|##\|.T\|__\|__\|}

regexp が受け取る式は です。これは、が以前に処理され\*05.\|__\|##\|.T\|__\|__\|た後のものです。"\\*05.\\|__\\|##\\|.T\\|__\\|__\\|"

于 2013-08-08T16:13:06.863 に答える