我的意思是($ H,$ M,$ S)= $ date = ~m {^([0-9] {2}):( [0-9] {2}):( [0-9] { 2})}在perl中

时间:2016-01-06 10:15:50

标签: regex perl

我是perl的新手。任何人都可以解释以下代码行的含义:

my ($H,$M,$S) = $date =~ m{^([0-9]{2}):([0-9]{2}):([0-9]{2})}

我假设执行此行$H后,$M$S将从$date中提取值。任何人都可以解释以获得更好的理解吗?

3 个答案:

答案 0 :(得分:8)

它尝试将$date变量的内容与正则表达式匹配:

^([0-9]{2}):([0-9]{2}):([0-9]{2})

正则表达式基本上意味着:从字符串的开头,应该有两个数字和冒号重复三次。这三个两位数字中的每一个都包含在一个组中。

最后,将三个组的匹配分配给局部变量$H$M$S

<小时/> 例如,如果

$date = "10:37:21 2016.01.02";

然后

$H = "10";
$M = "37";
$S = "21";

答案 1 :(得分:1)

  

任何人都可以解释以获得更好的理解吗?

你需要开始意识到两件事:

  1. 列出上下文

  2. 标量背景

  3. 匹配运算符m//将根据=符号左侧的内容提供不同的结果。看看这个:

    use strict;
    use warnings; 
    use 5.020;
    
    my $result =  "abc" =~ m/a(.)(.)/;
    say $result;   #=> 1
    
    my @results = "abc" =~ m/a(.)(.)/;
    for my $result (@results) {
        say $result;
    };
    
    --output:--
    b
    c
    

    $variable只能存储一件事,所以当=符号的左侧有$变量时,$变量会查找匹配运算符{{1} },在m//标志的右侧,并喊道,“嘿,我只能在这里存放一件东西,请给我一件事,拜托!”匹配运算符通过返回1来响应,如果匹配则返回true;或0,如果没有匹配则为假。

    另一方面,当=位于@variable符号的左侧时,数组会查看=运算符并调出来,“嘿,我可以在这里存放一堆东西,请给我一堆东西,拜托!“如果匹配,匹配运算符通过返回与正则表达式中的捕获组匹配的内容来响应;如果没有匹配,匹配运算符将返回m//

    在第一种情况下,据说()为匹配运算符提供$variable。在第二种情况下,据说scalar context为匹配运算符提供@variable。不要让这些条款吓到你。你知道他们现在的意思。

    接下来,当你写下这个:

    list context

    您正在my ($H,$M,$S) = 符号的左侧创建多个变量。他们一致地呼叫=标志另一侧的匹配运营商,“嘿,我们这里有很多人,请给我们一堆东西!特别是=语法为匹配运算符提供my,该运算符位于list context符号的右侧:

    =

    请注意,如果您用于匹配运算符的分隔符为my ($group1, $group2) = "abc" =~ m/a(.)(.)/; say $group1; #=> b say $group2; #=> c ,则您不必编写前导m/.../,因此通常您会看到上面的示例写为:

    m

    当您像使用my ($group1, $group2) = "abc" =~ /a(.)(.)/; 一样使用大括号时,则必须编写前导m{...}{...}

答案 2 :(得分:0)

您可以使用更容易理解的更简单的正则表达式来执行您想要的操作:

 \d{2}  #\d means a digit, {2} means twice,
        #so this matches two consecutive digits

以下是如何使用该正则表达式:

#Just blindly use all three of these in every program:
use strict;
use warnings; 
use 5.020;    

my $date = "10:37:21 2016.01.02";

my ($H,$M,$S) = $date =~ /\d{2}/g;  #g => global, Find all matches in the string

say $H;  #say() is the same as print() with a newline at the end
say $M;
say $S;

--output:--
10
37
21

正则表达式从字符串的开头开始,查找两个连续的数字并找到10,这是一个匹配;然后正则表达式跳过:并找到37,这是匹配;然后正则表达式跳过:并找到21,所以这是匹配;等等。

当您将所有匹配分配给三个变量时,前三个匹配将分配给三个变量,其余匹配将被丢弃。