📜  Perl - 使用正则表达式从字符串中提取日期

📅  最后修改于: 2022-05-13 01:55:17.120000             🧑  作者: Mango

Perl - 使用正则表达式从字符串中提取日期

通常在 Perl 中,我们必须读取 CSV(逗号分隔值)文件来提取所需的数据。有时文件名中包含日期,例如示例 2014-02-12T11:10:10.csv,或者文件中可能有一列包含日期。这些日期可以是任何模式,如YYYY-MM-DDThh:mm:ssdd/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