В регулярных выражениях используйте технику, которую я люблю называть tack-and-stretch: привязка к функциям, которые, как вы знаете, будут там (tack), а затем захватывает то, что находится между (stretch).
В этом случае вы знаете, что соответствует одно присвоение
\b\w+=.+
и многие из них повторяются в $string
. Помните, что \b
означает границу слова:
Граница слова (\b
) - это точка между двумя символами, имеющая \w
на одной стороне от нее и \W
на другой стороне (в любом порядке), считая воображаемые символы начало и конец строки как совпадающие с \W
.
Значения в назначениях могут быть немного сложными для описания с помощью регулярного выражения, но вы также знаете, что каждое значение будет заканчиваться пробелом - хотя не обязательно первым встречным пробелом! - после другого назначения или конца -string.
Чтобы избежать повторения шаблона утверждения, скомпилируйте его один раз с qr//
и повторно используйте его в своем шаблоне вместе с прогнозным утверждением (?=...)
, чтобы растянуть совпадение просто достаточно далеко, чтобы захватить все значение, а также предотвратить его перетекание в имя следующей переменной.
Сопоставление с вашим шаблоном в контексте списка с m//g
дает следующее поведение:
Модификатор /g
определяет глобальное сопоставление с образцом, то есть сопоставление столько раз, сколько возможно в пределах строки. Как это ведет себя, зависит от контекста. В контексте списка он возвращает список подстрок, сопоставленных с любыми захватывающими скобками в регулярном выражении. Если круглых скобок нет, возвращается список всех совпадающих строк, как если бы вокруг всего шаблона были круглые скобки.
В шаблоне $assignment
используется нежадный .+?
для обрезания значения, как только упреждающий просмотр увидит другое назначение или конец строки. Помните, что совпадение возвращает подстроки из всех , захватывающих подшаблоны, поэтому в альтернативном прогнозе используется не захват (?:...)
. qr//
, напротив, содержит неявные круглые скобки.
#! /usr/bin/perl
use warnings;
use strict;
my $string = <<'EOF';
var1=100 var2=90 var5=hello var3="a, b, c" var7=test var3=hello
EOF
my $assignment = qr/\b\w+ = .+?/x;
my @array = $string =~ /$assignment (?= \s+ (?: $ | $assignment))/gx;
for ( my $i = 0; $i < scalar( @array ); $i++ )
{
print $i.": ".$array[$i]."\n";
}
Выход:
0: var1=100
1: var2=90
2: var5=hello
3: var3="a, b, c"
4: var7=test
5: var3=hello