我需要帮助理解下面的正则表达式。
有人可以告诉我这意味着什么m/^(\d+\/\d+\/\d+\s\d+\:\d+\:\d+\.\d+)/msx
foreach my $line ( @{ $self->{'stdout'} } ) {
if ( $line =~ m/^(\d+\/\d+\/\d+\s\d+\:\d+\:\d+\.\d+)/msx ) {
$timestamp = $1;
}
答案 0 :(得分:1)
这个原始正则表达式
m/^(\d+\/\d+\/\d+\s\d+\:\d+\:\d+\.\d+)/msx
是一个编写得非常糟糕的模式,与日期/时间字符串相匹配,看起来像2014/07/31 22:53:42.123
由于它不包含任何点.
,因此/s
修饰符是多余的。
/x
修饰符允许添加空格布局,所以我们也可以使用不同的分隔符,以便斜线不需要转义
m{ ^ ( \d+ / \d+ / \d+ \s \d+ : \d+ : \d+ \. \d+ ) }mx
这样匹配
/m
修饰符生效)所以,正如我所说,它会匹配(和捕获)
2014/07/31 22:53:42.123
它也匹配
0/1/2 3:4:5.6
我希望有帮助
答案 1 :(得分:1)
此
if ( $line =~ m/^(\d+\/\d+\/\d+\s\d+\:\d+\:\d+\.\d+)/msx ) {
是非常难以理解的,尽管作者开始让它可读,因为它有/x
标志(允许空格,但没有使用),但它仍然受到反斜视的影响并且不限制与真正的意义相匹配。
使用不同的分隔符重写它可以去掉一些反斜杠:
if ( $line =~ m{^(\d+/\d+/\d+\s\d+:\d+:\d+\.\d+)}msx ) {
添加空格并使用[.]
来匹配单个点并添加注释可以更好地了解匹配的内容:
if ( $line =~ m{^ # (start of line)
( # (capture group $1)
\d+ / \d+ / \d+ # digit(s) slash digit(s) slash digit(s)
\s # ANY whitespace character (space, tab, etc)
\d+ : \d+ : \d+ # digit(s) colon digit(s) colon digit(s)
[.] \d+ # dot digit(s)
) # (end capture group $1)
}msx ) {
其中digit(s)
表示一个或多个数字0-9(或任何utf8数字)。因此,这将很乐意匹配类似“00000/0000/0000000000 0000:0000000000000000000000:000000.0000”的内容,但似乎它们意味着匹配,例如“0000/00/00 00:00:00.000”(时间戳包括毫秒)。
一个更好的正则表达式(匹配它不应该匹配的东西的可能性更低,虽然它固定在线的开头,所以这里没有真正的实际区别,但作为一般规则,最好尽可能具体到你可以)会是这样的:
if ( $line =~ m{^
(
[0-9]{4} / [0-9]{2} / [0-9]{2}
[ ] # space character
[0-9]{2} : [0-9]{2} : [0-9]{2}
[.] [0-9]{3}
)
}msx ) {
有了这方面的话,其他链接的正则表格联机手册应该更有意义。