1

最近は正規表現を学んでいますが、少し大変そうです。TCLでいくつかのコードを読んでいますが、何を一致させたいですか?

regexp ".* (\[\\d]\{3\}:\[\\d]\{3\}:\[\\d]\{3\}.\[\\d]\{5\}).\[^\\n]" $input
4

2 に答える 2

8

文字のエスケープを解除すると、次のようになります。

。*([\ d] {3}:[\ d] {3}:[\d]{3}。[\d]{5})。[^ \ n]

この用語は、連続する桁数[\d]{x}と一致します。xしたがって、括弧内の部分は、フォームの何かと一致します###:###:###?#####(ここで#、任意の数字と?任意の文字を使用できます)。括弧自体は一致していません。入力のどの部分を「キャプチャ」して呼び出し元に返すかを指定するために使用されています。.このシーケンスの後には、単一の文字(任意の文字)に一致する単一のドットが続きます。末尾は、改行以外[^\n]の1文字に一致します(括弧で囲まれた式の先頭にあるaは、一致を反転します)。最初の用語は、任意の長さ(ゼロでも)の文字のシーケンスに一致し、その後にスペースが続きます。^.*

これらすべてを考慮に入れると、この正規表現は行の中央から一連の数字を抽出するように見えます。数値の形式を指定すると、その形式のタイムスタンプを検索している可能性がありhours:minutes:seconds.millisecondsます(ただし、その場合は、代わりに使用する必要が{1,3}あり{1,5}ます)。末尾の.[^\n]用語は、行の終わりまたはその近くにあるタイムスタンプを除外しようとしているように見えます。タイムスタンプ付きのログには、多くの場合、タイムスタンプの後に何らかの区切り文字(、、:スペース>など)が続きます。このような正規表現を使用して、タイムスタンプはあるがメッセージがない「空白」行を無視して、ログからタイムスタンプを抽出できます。

更新: TCL8.4を使用した例を次に示します。

% set re ".* (\[\\d]\{3\}:\[\\d]\{3\}:\[\\d]\{3\}.\[\\d]\{5\}).\[^\\n]"
% regexp $re "TEST: 123:456:789:12345> sample log line"
1
% regexp $re " 111:222:333.44444 foo"
1
% regexp $re "111:222:333.44444 foo"
0
% regexp $re " 111:222:333.44444 "
0
% regexp $re " 10:44:56.12344: "
0
%
% regexp $re "TEST: 123:456:789:12345> sample log line" match data
1
% puts $match
TEST: 123:456:789:12345>
% puts $data
123:456:789:12345

最初の2つの例は式と一致します。3番目は、最初の数列の前にスペース文字がないために失敗します。4つ目は、末尾のスペースの後の最後に改行以外の文字がないために失敗します。数値シーケンスに十分な桁がないため、5番目は失敗します。入力の後にパラメーターを渡すことにより、式に一致した入力の部分と、括弧を使用して「キャプチャ」されたデータを格納できます。コマンドの詳細については、TCLwikiを参照してくださいregexp

TCLの興味深い部分は、との両方をエスケープする必要がある一方で、キャラクターをエスケープする必要があるが、をエスケープする必要が[ないことです。]{}

于 2012-04-17T15:42:56.353 に答える
0
.* ==> match junk part of the input

 ( ==> start capture

 \[\\d]\{3\}: ==> match 3 digits followed by ':'

 \[\\d]\{3\}: ==> match 3 digits followed by ':'

 \[\\d]\{3\}. ==> match 3 digits followed by any character

\[\\d]\{5\} ==> match 5 digits

). ==> close capture and match any character

\[^\\n] ==> match a character that is not a newline
于 2012-04-17T15:32:15.640 に答える