Я пытаюсь преобразовать основанное на регулярных выражениях решение проблемы рюкзака с Perl на raku. Подробная информация о Perlmonks
Решение Perl создает это регулярное выражение:
(?<P>(?:vvvvvvvvvv)?)
(?<B>(?:vv)?)
(?<Y>(?:vvvv)?)
(?<G>(?:vv)?)
(?<R>(?:v)?)
0
(?=
(?(?{ $1 })wwww|)
(?(?{ $2 })w|)
(?(?{ $3 })wwwwwwwwwwww|)
(?(?{ $4 })ww|)
(?(?{ $5 })w|)
)
Который сопоставляется с vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww
. После этого хэш соответствия %+
содержит предметы, которые нужно положить в мешок.
Моя конверсия раку:
$<B> = [ [ vv ]? ]
$<P> = [ [ vvvvvvvvvv ]? ]
$<R> = [ [ v ]? ]
$<Y> = [ [ vvvv ]? ]
$<G> = [ [ vv ]? ]
0
<?before
[ { say "B"; say $/<B>; say $0; say $1; $1 } w || { "" } ]
[ { say "P"; say $/<P>; say $0; say $1; $2 } wwww || { "" } ]
[ { say "R"; say $/<R>; say $0; say $1; $3 } w || { "" } ]
[ { say "Y"; say $/<Y>; say $0; say $1; $4 } wwwwwwwwwwww || { "" } ]
[ { say "G"; say $/<G>; say $0; say $1; $5 } ww || { "" } ]
Что также соответствует vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww
. Но объект соответствия $/
не содержит ничего полезного. Кроме того, все мои отладочные say
говорят Nil, так что в этот момент обратная ссылка не работает?
Вот мой тестовый сценарий:
my $max-weight = 15;
my %items =
'R' => { w => 1, v => 1 },
'B' => { w => 1, v => 2 },
'G' => { w => 2, v => 2 },
'Y' => { w => 12, v => 4 },
'P' => { w => 4, v => 10 }
;
my $str = 'v' x %items.map(*.value<v>).sum ~
'0' ~
'w' x $max-weight;
say $str;
my $i = 0;
my $left = my $right = '';
for %items.keys -> $item-name
{
my $v = 'v' x %items{ $item-name }<v>;
my $w = 'w' x %items{ $item-name }<w>;
$left ~= sprintf( '$<%s> = [ [ %s ]? ] ' ~"\n", $item-name, $v );
$right ~= sprintf( '[ { say "%s"; say $/<%s>; say $0; say $1; $%d } %s || { "" } ]' ~ "\n", $item-name, $item-name, ++$i, $w );
}
use MONKEY-SEE-NO-EVAL;
my $re = sprintf( '%s0' ~ "\n" ~ '<?before ' ~ "\n" ~ '%s>' ~ "\n", $left, $right );
say $re;
dd $/ if $str ~~ m:g/<$re>/;
1 ответ
Этот ответ охватывает только то, что происходит не так. Это не касается решения. Я не зарегистрировал соответствующие ошибки. Я еще даже не искал очереди ошибок, чтобы увидеть, могу ли я найти отчеты, соответствующие одной или обеим двум проблемам, которые я обнаружил.
my $lex-var;
sub debug { .say for ++$, :$<rex-var>, :$lex-var }
my $regex = / $<rex-var> = (.) { $lex-var = $<rex-var> } <?before . { debug }> / ;
'xx' ~~ $regex; say $/;
'xx' ~~ / $regex /; say $/;
Дисплеи :
1
rex-var => Nil
lex-var => 「x」
「x」
rex-var => 「x」
2
rex-var => Nil
lex-var => 「x」
「x」
Сосредоточившись сначала на первом вызове debug
(строки, начинающиеся с 1
и заканчивающиеся на rex-var => 「x」
), мы видим, что:
Что-то пошло не так во время вызова
debug
: сообщается, что$<rex-var>
имеет значениеNil
.Когда сопоставление с регулярным выражением завершено и мы возвращаемся к основной строке,
say $/
сообщает о полном и правильно заполненном результате, включающем именованное совпадениеrex-var
.
Чтобы понять, что пошло не так, прочитайте большую часть мой ответ на другой вопрос SO. Вы можете смело пропустить Использование ~
. Сноски 1, 2 и 6 также, вероятно, совершенно не имеют отношения к вашему сценарию.
Для второго совпадения мы видим, что не только $<rex-var>
сообщается как Nil
во время вызова debug
, переменная окончательного совпадения, как сообщается в основной строке со вторым say $/
, также отсутствует совпадение rex-var
. И единственная разница в том, что регулярное выражение $regex
вызывается из внутри внешнего регулярного выражения.
Похожие вопросы
Связанные вопросы
Новые вопросы
regex
Регулярные выражения предоставляют декларативный язык для сопоставления шаблонов в строках. Они обычно используются для проверки строк, разбора и преобразования. Укажите язык (PHP, Python и т. д.) или инструмент (grep, VS Code, Google Analytics и т. д.), который вы используете. Не размещайте вопросы, требующие объяснения того, что означает символ или чему будет соответствовать конкретное регулярное выражение.
|| { "" }
в вашем предварительном просмотре?