Perl - 使用正则表达式从字符串中提取日期
通常在 Perl 中,我们必须读取 CSV(逗号分隔值)文件来提取所需的数据。有时文件名中包含日期,例如示例 2014-02-12T11:10:10.csv,或者文件中可能有一列包含日期。这些日期可以是任何模式,如YYYY-MM-DDThh:mm:ss或dd/mm/yyyy hh.mm.ss 。处理这些日期; Perl 脚本应该足够灵活以处理字符串中不同类型的日期格式。我们需要使用正则表达式功能从字符串中提取日期。正则表达式是字符串字符,用于定义您正在查看的特定模式。应用正则表达式的基本方法是使用模式绑定运算符=~ 和 !~。
在 Perl 中有多个可用于处理日期和时间的库,例如 Date::Parse 和 Time::Piece;这两个库都带有许多灵活的函数来处理更复杂的需求。但是这些库不是标准 Perl 模块的一部分,您需要单独安装它们。
对于一般日期格式,无需安装任何新库就可以找到特定的正则表达式。让我们看一些在 Perl 中从字符串解析日期的示例。
在我们查看从字符串中提取日期的示例之前,我们应该查看用于解析字符串中的表达式的这些元符号:^ metacharacter matches the beginning of the string $ metasymbol matches the end of the string * matches 0 or more occurrences of preceding expression + matches 1 or more occurrence of preceding expression ? matches 0 or 1 occurrence of preceding expression
下面是一些简短的例子。
/^$/ | # nothing in the string (start and end are adjacent) |
/(\d\s) {3}/ | a three digits, each followed by a whitespace.e.g:6 7 8 |
/(a.)+/ | matches a string in which every next letter is a |
/^\d+/ | string starts with one or more digits |
/\d+$/ | string ends with one or more digits |
正则表达式不需要单独的模块。它内置于 Perl(任何版本)中。所以你应该在你的系统上安装 Perl(任何版本)。我们将看到一些使用 Perl 正则表达式以不同格式从字符串中提取日期的示例。
示例 1:
在本例中,我们将看到如何从 Perl 中的字符串中提取具有模式 yyyy-mm-ddThh:mm:ss 的日期。下面的示例 1 显示了一个字符串sample2018-03-21T12:10:10.csv,我们需要从中提取年、月和日期变量中的日期,以使其可用于进一步的脚本。
此处,正则表达式 \d\d\d\d 确保字符串中的日期模式应以 4 位数字模式开头。如果不是,那么它可能会抛出一个未初始化的变量异常,因为字符串中缺少模式。
/d?/d 是什么意思?此模式确保月、日、小时、分钟和秒可以是 1 位数或 2 位数。
例如:
2013-9-21T11:3:30
2014-12-3T9:1:10
所以 /d?/d 将确保表达式留给?是可选的,它将在没有任何错误的情况下执行。
Perl
#!/usr/bin/perl
# your code here
my $str = "sample2018-03-21T12:10:10.csv";
my (($year, $month, $day, $hour, $min, $sec) =
$str =~ /(\d\d\d\d)-(\d?\d)-(\d?\d)T(\d?\d):(\d?\d):(\d?\d)/);
print "year : $year month:$month day:$day - hour:$hour minute:$min seconds:$sec\n";
Perl
#!/usr/bin/perl
# your code here
my $str1 = "test_28/04/2017 11.00.00";
my (($month1, $day1, $year1, $hour1, $min1, $sec1) =
$str1 =~ m{(\d?\d)/(\d?\d)/(\d\d\d\d) (\d\d)\.(\d\d)\.(\d\d)});
print "year:$year1 month:$month1 day:$day1 - hour:$hour1 minute:$min1 seconds:$sec1\n";
Perl
#!/usr/bin/perl
# your code here
my $string = 'Date: Tue, 11 Feb 2014 11:01:57 +0100 (CET)';
my ($day3, $month3, $year3) = $string =~ /Date:.+?(\d+)\s(.+?)\s(\d+)/;
print "Day:$day3 month:$month3 year:$year3\n";
输出:
year : 2018 month:03 day:21 - hour:12 minute:10 seconds:10
示例 2:
在这个例子中,我们将看到如何使用模式 mm/dd/yyyy hh.mm.ss 从字符串中提取日期。日期可以是文件名的一部分,也可以是内容。因此,以下示例将有助于从字符串解析格式为 mm/dd/yyyy hh:mm:ss 的日期。在这个例子中,我们采用了一个字符串test_28/04/2017 11.00.00 ;其中日期以 2 位数字 28 开头,后跟反斜杠 /
在这里, (\d?\d) 正则表达式确保字符串以 2 或 1 位数字后跟 / 的模式开头。反斜杠 \ 放在 .确保它只匹配点而不是像通常那样匹配每个字符。
珀尔
#!/usr/bin/perl
# your code here
my $str1 = "test_28/04/2017 11.00.00";
my (($month1, $day1, $year1, $hour1, $min1, $sec1) =
$str1 =~ m{(\d?\d)/(\d?\d)/(\d\d\d\d) (\d\d)\.(\d\d)\.(\d\d)});
print "year:$year1 month:$month1 day:$day1 - hour:$hour1 minute:$min1 seconds:$sec1\n";
输出:
year:2017 month:28 day:04 - hour:11 minute:00 seconds:00
示例 3:
在这里,我们将看到另一种日期模式,即 {Day}, dd {mon} yyyy hh:mm:ss,例如 Tue,11 Feb 2014 11:01:54 +0100 (CET);有时 CSV 文件具有上述格式的日期列值,Perl 操作无法读取该格式,因此我们希望从该格式中提取年、月和日,并根据需要使用它。
在这里, .+?(\d+) regex 表示在日期数字 11 之前会有一些字符,之后 \s(.+?) regex字符日期后跟一个空格和字符串,即 Feb, s(\d+ )/ regex 确保 11 Feb 后跟一个空格和多个数字,即 2014。我们将这些值保存在为日、月和年定义的变量中;可以在进一步的脚本中使用。
珀尔
#!/usr/bin/perl
# your code here
my $string = 'Date: Tue, 11 Feb 2014 11:01:57 +0100 (CET)';
my ($day3, $month3, $year3) = $string =~ /Date:.+?(\d+)\s(.+?)\s(\d+)/;
print "Day:$day3 month:$month3 year:$year3\n";
输出:
Day:11 month:Feb year:2014