интерполировать массив в соответствии для функций И, ИЛИ, НЕ
Я не знаю лучшего решения, чем Мориц для AND
.
Я покрываю OR
ниже.
Один естественный способ написать NOT
списка токенов совпадения - это использовать отрицательные версии lookahead или утверждения lookbehind, например:
my $a="123 ab 4567 cde";
my @b=<23 b cd 567>;
say $_>>.pos given $a ~~ m:g/ <!before @b> /;
отображает:
(0 2 3 4 6 7 9 10 11 13 14 15)
, что соответствует позициям 12 матчей , а не 23
, b
, cd
или 567
inстрока "123 ab 4567 cde"
, показанная линией ^
s ниже, которая указывает на каждую из совпадающих позиций символов:
my $a="123 ab 4567 cde";
^ ^^^ ^^ ^^^ ^^^
0123456789012345
Я пытаюсь заново выполнить свою программу для соответствия-all, match-any, match-none элементов массива.
Эти звуковые соединения, как и некоторые другие вопросы, явно касаются соединений.Если вы подключились к своей существующей программе, мне / другим будет легче увидеть, что вы пытаетесь сделать.
(1)
||@b
соответствует крайнему левому краю соответствующий токен в @b
, а не самый длинный один.
Запись |@b
, с одинарным |
, чтобы соответствовать самый длинный соответствующий токен в @b
.Или, что еще лучше, напишите просто @b
, что является сокращением для одной и той же вещи.
Обе эти схемы сопоставления (|@b
или ||@b
), как и любые другие сопоставления, подчиняютсякак работает механизм регулярных выражений, как кратко описано Морицем и более подробно ниже.
Когда механизм регулярных выражений сопоставляет регулярное выражение со строкой ввода, он запускается в начале регулярного выражения и в начале вводаstring.
Если он не соответствует, он проходит мимо первого символа во входной строке, отказываясь от этого символа, и вместо этого делает вид, что входная строка началась с ее символа second .Затем он снова пытается сопоставить, начиная с начала регулярного выражения, но второй символ входной строки.Он повторяет это до тех пор, пока не доберется до конца строки или не найдет совпадение.
В вашем примере двигатель не может соответствовать прямо в начале 123 ab 4567 cde
, но успешно сопоставляет 23
, начиная свторая позиция персонажа.Итак, все сделано - и 567
в вашем шаблоне соответствия не имеет значения.
Один из способов получить ожидаемый ответ:
my $a="123 ab 4567 cde";
my @b=<23 b cd 567>;
my $longest-overall = '';
sub update-longest-overall ($latest) {
if $latest.chars > $longest-overall.chars {
$longest-overall = $latest
}
}
$a ~~ m:g/ @b { update-longest-overall( $/ ) } /;
say $longest-overall;
отображает:
「567」
Использование :g
объясняется ниже.
(2)
|@b
или ||@b
в основном коде означают нечто совершенно не связанное с тем, что они означают внутри регулярного выражения.Как видите, |@b
совпадает с @b.Slip
.||@b
означает @b.Slip.Slip
, что оценивается как @b.Slip
.
Чтобы сделать "параллельное" самое длинное совпадение с шаблоном побед OR
элементов @b
, напишите @b
(или|@b
) внутри регулярного выражения .
Чтобы сделать "последовательный" самый левый-матч-шаблон-побед OR
элементов @b
, напишите ||@b
внутриregex.
До сих пор я не мог понять, что делают &
и &&
, когда используются для префикса массива в регулярном выражении.Мне кажется, есть несколько ошибок, связанных с их использованием.
В некотором коде в вашем вопросе вы указали наречие :g
.Это заставляет механизм не останавливаться, когда он находит совпадение, а вместо этого проходить мимо подстроки, с которой он только что совпал, и начинать пытаться снова сопоставить далее во входной строке.
(Существуют другие наречия. :ex
Наречие является самым экстремальным. В этом случае, когда есть совпадение в данной позиции во входной строке, движок пытается сопоставить любой другой шаблон совпадения в той же позиции врегулярное выражение и входная строка. Он продолжает делать это независимо от того, сколько совпадений он накапливает, пока не попробует каждое последнее возможное совпадение в этой позиции в регулярном выражении и входной строке. Только когда все эти возможности исчерпаны, он переместится на один символ вперед ввходную строку, и пытается исчерпывающе сопоставить все заново.)
(3)
Мой лучший снимок:
my $a="123 ab 4567 cde";
my @b=<23 b cd 567>;
my &choose = &any;
say so choose do for @b -> $z {
$a ~~ / { say "==>$a -->$z"; } $z /
}