这些天我正在学习正则表达式,但对我来说似乎有点困难.我正在阅读TCL中的一些代码,但它想要匹配什么?
regexp ".* (\[\\d]\{3\}:\[\\d]\{3\}:\[\\d]\{3\}.\[\\d]\{5\}).\[^\\n]" $input
Run Code Online (Sandbox Code Playgroud)
如果取消转义字符,则会得到以下内容:
.* ([\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
Run Code Online (Sandbox Code Playgroud)
前两个示例与表达式匹配.第三个失败是因为它在第一个数字序列之前缺少空格字符.第四个失败,因为它在尾随空格后的末尾没有非换行符.第五个失败是因为数字序列没有足够的数字.通过在输入后传递参数,您可以存储与表达式匹配的输入部分以及使用括号"捕获"的数据.有关该命令的详细信息,请参阅TCL wikiregexp.
与TCL有趣的部分是你必须逃避[角色而不是逃避角色],{而且}需要逃避.