2016-01-06 2 views
2

Я новичок в perl. Может кто-нибудь объяснить смысл следующей строки кода:

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

Я предполагаю, что после выполнения этой строки $H, $M и $S будут иметь значения, извлеченные из $date. Может ли кто-нибудь объяснить, чтобы лучше понять?

+0

'()' обозначает группы захвата в регулярном выражении. Вы захватываете, генерируете список, а затем назначаете список LHS (скалярных переменных) – Sobrique

ответ

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"; 
+0

Спасибо за четкий ответ. Просто чтобы подтвердить, строка ввода должна быть в следующем формате, чтобы соответствовать регулярному выражению: 05:15:25 Верно ли это? –

+0

Получил. Благодаря! –

+1

@siju, да, он должен начинаться с этого формата, он может иметь что-то после этого. – ndn

1

Может кто-нибудь объяснить, чтобы получить лучшее понимание?

Вы должны начать осознавать две вещи:

  1. контекстного список

  2. скалярного контекст

Оператор матча, 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 может хранить только одну вещь, поэтому, когда есть переменная $ на левой стороне = знака, то переменная $ смотрит на оператора матча, m//, на правая сторона знака = и звонит: «Эй, я могу хранить только одну вещь здесь, просто дай мне одну вещь, пожалуйста!» Оператор матча отвечает, возвращая 1, для true, если было совпадение; или 0, для false, если не было соответствия.

С другой стороны, когда @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{...}{...}, тогда вам нужно написать ведущий m.

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, так что это совпадение; то regex перескакивает через : и находит 37, так что это совпадение; то regex перескакивает через : и находит 21, так что это совпадение; и т. д. и т. д.

Когда вы назначаете все соответствия трем переменным, первые три матча присваиваются трем переменным, а остальные совпадения отбрасываются.

Смежные вопросы