Regex my($H,$M,$S)=$date=~M{^([0-9]{2}):([0-9]{2}):([0-9]{2})在perl中的含义

Regex my($H,$M,$S)=$date=~M{^([0-9]{2}):([0-9]{2}):([0-9]{2})在perl中的含义,regex,perl,Regex,Perl,我是perl新手。有人能解释一下以下代码行的含义吗 my ($H,$M,$S) = $date =~ m{^([0-9]{2}):([0-9]{2}):([0-9]{2})} 我假设在执行这一行之后,$H,$M和$S将从$date中提取值。有人能解释一下以便更好地理解吗?它尝试将$date变量的内容与正则表达式匹配: ^([0-9]{2}):([0-9]{2}):([0-9]{2}) 正则表达式的基本意思是:从字符串开始,应该有两个数字和冒号重复三次。这三个两位数中的每一个都包含在一个组中

我是perl新手。有人能解释一下以下代码行的含义吗

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

我假设在执行这一行之后,
$H
$M
$S
将从
$date
中提取值。有人能解释一下以便更好地理解吗?

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

^([0-9]{2}):([0-9]{2}):([0-9]{2})
正则表达式的基本意思是:从字符串开始,应该有两个数字和冒号重复三次。这三个两位数中的每一个都包含在一个组中

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

例如,如果

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

有人能解释一下以便更好地理解吗

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

  • 列表上下文

  • 标量上下文

  • 匹配运算符
    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
    只能存储一个东西,因此当在
    =
    符号的左侧有一个$variable时,$variable将目光转向
    =
    符号右侧的匹配操作符
    m/
    ,并大声呼叫,“嘿,我只能在这里存储一个东西,请给我一个东西!”匹配操作符通过返回1进行响应,如果存在匹配,则返回true;如果没有匹配项,则0表示false

    另一方面,当一个
    @变量
    位于
    =
    符号的左侧时,数组会向
    m//
    操作符看去,并喊道:“嘿,我可以在这里存储一堆东西,请给我一堆东西!”匹配操作符通过返回与正则表达式中的捕获组匹配的内容(如果存在匹配)进行响应;如果没有匹配项,则match操作符返回
    ()

    在第一种情况下,
    $variable
    被称为为match操作符提供了
    标量上下文。在第二种情况下,
    @变量
    被认为为匹配运算符提供了
    列表上下文
    。不要让那些术语吓到你。你现在明白他们的意思了

    接下来,当你写这篇文章时:

    my ($H,$M,$S) = 
    
    您正在
    =
    符号的左侧创建多个变量。他们齐声呼叫
    =
    符号另一侧的匹配运算符,“嘿,这里有很多人,请给我们一堆东西!特定的
    my
    语法为
    =
    符号右侧的匹配运算符提供了
    列表上下文

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

    my ($group1, $group2) = "abc" =~ /a(.)(.)/;
    

    当您像以前那样使用大括号时:
    m{…}{…}
    ,那么您必须编写前导的
    m

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

     \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,这是一个匹配;等等


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

    感谢您给出了清晰的答案。请确认,输入字符串应采用以下格式以匹配正则表达式:05:15:25是否正确?@siju,是的,它应以该格式开头t、 不过,它也可以有后面的内容。
    ()
    表示正则表达式中的捕获组。您捕获、生成一个列表,然后分配给LHS的“列表”(标量变量)
    #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