使用PERL正则表达式获取时间戳

时间:2016-10-16 20:42:51

标签: regex perl timestamp

我很难找到一个时间戳,其中日,月和年用点分隔,虽然我选择的正则表达式在匹配仅执行一次时似乎工作得很好。

这是我的文字行:

TIMESTAMP: 08.08.2016 00:33:01

以下是代码:

#!/usr/bin/perl -w
#looking for timestamp in the following format: TIMESTAMP: 08.08.2016   00:33:01

my $TIMESTAMP;
my $TXT;

$TXT = "TIMESTAMP: 08.08.2016 00:33:01";

#matching for MACRO. example:   TIMESTAMP: 2016-09-18T15:07:20.246Z
($TIMESTAMP = $TXT) =~ /^TIMESTAMP: ([0-9]{1,4}-[0-9]{1,2}-[0-9] {1,2})T([0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}).[0-9]+Z/;
print "\ncheck1)the TIMESTAMP value is:$TIMESTAMP\n";
if (! defined $1) {

#matching for MM. example:  TIMESTAMP: 08.08.2016 00:33:01
($TIMESTAMP = $TXT) =~ /^TIMESTAMP: ((?:\d+).(?:\d+).(?:\d+))\s((?:\d+):(?:\d+):(?:\d+))/;
print   "check2)the TIMESTAMP value is:$TIMESTAMP\n";
}

if (defined $1 and defined $2) {
    $TIMESTAMP = $1." ".$2;
    print "the timestamp is:$TIMESTAMP\n";
} else {

    $TIMESTAMP = "n/a\n";
    print "not all elements of TIMESTAMP were defined,   TIMESTAMP:$TIMESTAMP\n";
}

我使用regex101验证正则表达式是否有效,但是当我连续两次检查时,脚本无法传递组$1$2

更新

整理Perl代码

#!/usr/bin/perl -w

# Looking for timestamp in the following format: TIMESTAMP: 08.08.2016   00:33:01

my $TIMESTAMP;
my $TXT;

$TXT = "TIMESTAMP: 08.08.2016 00:33:01";

# Matching for MACRO. example:   TIMESTAMP: 2016-09-18T15:07:20.246Z

( $TIMESTAMP = $TXT ) =~ /^TIMESTAMP: ([0-9]{1,4}-[0-9]{1,2}-[0-9] {1,2})T([0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}).[0-9]+Z/;

print "\ncheck1) the TIMESTAMP value is:$TIMESTAMP\n";

if ( ! defined $1 ) {

    # matching for MM. example:  TIMESTAMP: 08.08.2016 00:33:01

    ( $TIMESTAMP = $TXT ) =~ /^TIMESTAMP: ((?:\d+).(?:\d+).(?:\d+))\s((?:\d+):(?:\d+):(?:\d+))/;

    print "check2)the TIMESTAMP value is:$TIMESTAMP\n";
}

if ( defined $1 and defined $2 ) {

    $TIMESTAMP = $1 . " " . $2;

    print "the timestamp is:$TIMESTAMP\n";
}
else {

    $TIMESTAMP = "n/a\n";

    print "not all elements of TIMESTAMP were defined,   TIMESTAMP:$TIMESTAMP\n";
}

2 个答案:

答案 0 :(得分:2)

您的代码运行正常,但您已将其设置为过于复杂

  • 您的意见是错误的,甚至不同意

  • 不需要在\d+

  • 内的正则表达式模式中包含每个(?: ... )
  • 您必须以正则表达式模式转义文字点.,否则它可以匹配任何字符

  • 最好使用/x修饰符和非正常的正则表达式,以便您可以添加空格以使其更具可读性

  • 捕获变量$1$2 ...是块范围的,但您希望它们是永久性的

这是一个有效的版本,并使用Data::Dump在代码中的几个点显示捕获的值

#!/usr/bin/perl

use strict;
use warnings 'all';

use Data::Dump;

my $text = "TIMESTAMP: 08.08.2016 00:33:01";

unless ( defined $1 ) {

    $text =~ / ^ TIMESTAMP: \s* (\d+\.\d+\.\d+) \s+ (\d+:\d+:\d+) /x;

    dd [ $1, $2 ];
}

dd [ $1, $2 ];

输出

["08.08.2016", "00:33:01"]
[undef, undef]

答案 1 :(得分:-1)

第二个正则表达式确实起作用 但神奇变量$ 1和$ 2的值是limited to the block that they are in 因此即使与第二个正则表达式匹配,对这些变量的检查也没有按预期工作。

但两种时间戳格式只能匹配1个正则表达式。

#!/usr/bin/perl -w
# Looking for timestamp

my $TIMESTAMP;
my $TXT;

$TXT = "TIMESTAMP: 2016-09-18T15:07:20.246Z";

$TXT =~ /(\d{2,4}[.-]\d{2}[.-]\d{2,4})[ T](\d{2}:\d{2}:\d{2})([.]\d+Z?)?/;

if (defined $1) {
    $TIMESTAMP = $1." ".$2;
    print "The TIMESTAMP is: $TIMESTAMP\n";
} else {
    $TIMESTAMP = "n/a\n";
    print "No TIMESTAMP found: $TXT\n";
}