Perl regex vs. Raku regex, motordaki farklılıklar?


10

Ben sırt çantası sorunu Perl raku için regex tabanlı bir çözüm dönüştürmek çalışıyorum. Perlmonks ile İlgili Ayrıntılar

Perl çözümü bu normal ifadeyi oluşturur:

(?<P>(?:vvvvvvvvvv)?)
(?<B>(?:vv)?)
(?<Y>(?:vvvv)?)
(?<G>(?:vv)?)
(?<R>(?:v)?)
0
(?=
(?(?{ $1 })wwww|)
(?(?{ $2 })w|)
(?(?{ $3 })wwwwwwwwwwww|)
(?(?{ $4 })ww|)
(?(?{ $5 })w|)
)

eşleşir vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Bundan sonra maç karması %+torbaya konacak öğeleri içerir.

Benim raku dönüşüm:

$<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 || { "" } ]

aynı zamanda eşleşir vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww. Ancak eşleme nesnesi, $/yararlı bir şey içermez. Ayrıca, hata ayıklamamın sayhepsi Nil diyor, bu noktada backreference çalışmıyor gibi görünüyor?

İşte benim test senaryom:

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
Bilginize, raku sorularına PerlMonks'ta izin verilir
ikegami

Yanıtlar:


1

Bu cevap sadece neyin yanlış gittiğini kapsar. Bir çözümü ele almaz. Karşılık gelen hataları dosyalamadım. Daha önce ortaya çıkardığım iki konudan birine veya her ikisine karşılık gelen raporları bulabileceğimi görmek için henüz hata kuyruklarını aramadım.

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 $/;

görüntüler:

1
rex-var => Nil
lex-var => x
x
 rex-var => x
2
rex-var => Nil
lex-var => x
x

İlk olarak debug(ile başlayan 1ve biten hatlar) ilk çağrısına odaklanarak şunu rex-var => 「x」görebiliriz:

  • Çağrısı sırasında bir şeyler ters gitti debug: $<rex-var>değere sahip olduğu bildirildi Nil.

  • Normal ifade eşleşmesi tamamlandığında ve ana hatta geri döndüğümüzde, belirtilen eşleşmeyi say $/içeren tam ve doğru şekilde doldurulmuş bir sonuç raporlanır rex-var.

Neyin yanlış gittiğini anlamaya başlamak için lütfen başka bir SO sorusuna verdiğim cevabın büyük kısmını okumayı düşünün . Kullanarak~ güvenli bir şekilde atlayabilirsiniz . 1,2 ve 6 numaralı dipnotlar da muhtemelen senaryonuzla tamamen alakasızdır.

İkinci maç için, sadece arama sırasında olduğu $<rex-var>rapor edilmediğini görüyoruz, ikinci maçın ana hattında rapor edildiği gibi son maç değişkeninde de maç eksik . Ve tek fark, normal ifadenin bir dış normal ifadenin içinden çağrılmasıdır .Nildebugsay $/rex-var$regex

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.