我是perl的新手。任何人都可以解释以下代码行的含义:
my ($H,$M,$S) = $date =~ m{^([0-9]{2}):([0-9]{2}):([0-9]{2})}
我假设执行此行$H
后,$M
和$S
将从$date
中提取值。任何人都可以解释以获得更好的理解吗?
答案 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)
任何人都可以解释以获得更好的理解吗?
你需要开始意识到两件事:
列出上下文
标量背景
匹配运算符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,所以这是匹配;等等。
当您将所有匹配分配给三个变量时,前三个匹配将分配给三个变量,其余匹配将被丢弃。