这个正则表达式试图匹配什么?

时间:2012-04-17 15:12:48

标签: regex tcl

这些天我正在学习regular expressions,但对我来说似乎有点困难。我正在阅读TCL中的一些代码,但它想要匹配什么?

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

2 个答案:

答案 0 :(得分:8)

如果您取消转义字符,则会收到以下内容:

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

术语[\d]{x}将匹配x个连续数字。因此,括号内的部分将匹配###:###:###?#####形式的某些内容(其中#可以是任何数字,?可以是任何字符)。括号本身不匹配,它们仅用于指定“捕获”输入的哪一部分并返回给调用者。在此序列之后是单个点.,它匹配单个字符(可以是任何字符)。尾随[^\n]将匹配任何的单个字符,除了换行符(括号表达式开头的^会反转匹配)。最开始的.*项匹配任意长度(甚至为零)的字符序列,后跟空格。

考虑到所有这些因素后,这个正则表达式似乎从一行中间提取了一系列数字。鉴于数字的格式,它可能正在寻找hours:minutes:seconds.milliseconds格式的时间戳(尽管如果是这种情况,则应使用{1,3}{1,5}代替)。尾随.[^\n]术语看起来可能正在尝试排除行尾或接近行尾的时间戳。带时间戳的日志通常具有时间戳,后跟某种分隔符(:>,空格等)。像这样的正则表达式可用于从日志中提取时间戳,同时忽略具有时间戳但没有消息的“空白”行。

<强>更新 以下是使用TCL 8.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

前两个示例与表达式匹配。第三个失败是因为它在第一个数字序列之前缺少空格字符。第四个失败,因为它在尾随空格后的末尾没有非换行符。第五个失败是因为数字序列没有足够的数字。通过在输入后传递参数,您可以存储与表达式匹配的输入部分以及使用括号“捕获”的数据。有关regexp命令的详细信息,请参阅the TCL wiki

TCL的有趣之处在于你必须逃避[字符,而不是],而{}都需要转义。

答案 1 :(得分: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