3

perlpacktutで詳しく説明されているように、X / Y *の解凍文字列を使用して、最初にバイトストリームの長さを取得し、次にその数のバイトを正確に読み取ることができます。ただし、たとえば、単純なASCII数値と文字列を使用した正規表現内で、そのようなものを見つけるのに苦労しています。たとえば、ベンコード文字列は次の形式です。

[length]:[bytes]
4:spam
4:spam10:green eggs

私はかつてこれをやってのけることができたのを覚えていますが、?? {}を使用するだけで、今はコードが手元にありません。これは、新しい5.10キャプチャ/後方参照の1つを使用して、?? {}(これは非常に実験的です)なしで実行できますか?

明白な表現は機能しません:

/(\d+)\:(.{\1})/g
/(\d+)\:(.{\g-1})/g
4

2 に答える 2

3

/gフラグとアンカーを使用した正規表現を使用して実行し\Gますが、スカラーコンテキストで実行します。これにより、最後のパターン一致(または最初のパターン一致の開始)の直後の文字列内の位置が維持されます。この方法で弦に沿って歩くことができます。長さを取得し、コロンをスキップしてから、substrを使用して適切な数の文字を選択します。実際にに割り当てることができるposので、抽出した文字に合わせて更新します。redo一致するものがなくなるまで:

use v5.10.1;

LINE: while( my $line = <DATA> ) {
    chomp( $line );
    {
    say $line;
    next LINE unless $line =~ m/\G(\d+):/g;  # scalar /g!
    say "\t1. pos is ", pos($line); 
    my( $length, $string ) = ( $1, substr $line, pos($line), $1 );
    pos($line) += $length; 
    say "\t2. pos is ", pos($line); 
    print "\tFound length $length with [$string]\n";
    redo;
    }
    }

__END__
4:spam6:Roscoe
6:Buster10:green eggs
4:abcd5:123:44:Mimi

最後の入力行のエッジケースに注意してください。これ3:は文字列の一部であり、新しいレコードではありません。私の出力は次のとおりです。

4:spam6:Roscoe
    1. pos is 2
    2. pos is 6
    Found length 4 with [spam]
4:spam6:Roscoe
    1. pos is 8
    2. pos is 14
    Found length 6 with [Roscoe]
4:spam6:Roscoe
6:Buster10:green eggs
    1. pos is 2
    2. pos is 8
    Found length 6 with [Buster]
6:Buster10:green eggs
    1. pos is 11
    2. pos is 21
    Found length 10 with [green eggs]
6:Buster10:green eggs
4:abcd5:123:44:Mimi
    1. pos is 2
    2. pos is 6
    Found length 4 with [abcd]
4:abcd5:123:44:Mimi
    1. pos is 8
    2. pos is 13
    Found length 5 with [123:4]
4:abcd5:123:44:Mimi
    1. pos is 15
    2. pos is 19
    Found length 4 with [Mimi]
4:abcd5:123:44:Mimi

このためのモジュールがあるかもしれないと思いました、そしてあります:Bencode。それは私がしたことをします。それは私が無料でたくさんの仕事をしたことを意味します。常に最初にCPANを見てください。モジュールを使用しない場合でも、その解決策を見ることができます:)

于 2012-03-16T10:13:00.310 に答える
1

いいえ、を使用せずにそれが可能だとは思いません。これは次の(??{ ... })ようになります。

/(\d++):((??{".{$^N}"}))/sg
于 2012-03-16T03:22:50.800 に答える