0

perl でファイルをストリーミングし、行をトークン化し、トークンを含めようとしています。

私は持っている:

while( $line =~ /([\/][\d]*[%].*?[%][\d]*[\/]|[^\s]+|[\s]+)/g ) {
  my $word = $1;
  #...
}

ただし、トークンにスペースがない場合は機能しません。

たとえば、私の行が次の場合:

$line = '/15%one (1)(2)%15/ is a /%good (1)%/ +/%number(2)%/.'

その行を次のように分割したいと思います。

$output =
[
  '/15%one (1)(2)%15/',
  ' ',
  'is',
  ' ',
  'a',
  '/%good (1)%/',
  ' ',
  '+',
  '/%number(2)%/',
  '.'
]

これを行う最善の方法は何ですか?

4

1 に答える 1

2

(?:(?!STRING).)*そのままSTRINGそのまま[^CHAR]*CHAR_

my @tokens;
push @tokens, $1
   while $line =~ m{
      \G
      ( \s+
      | ([\/])([0-9]*)%
        (?: (?! %\3\2 ). )*
        %\3\2
      | (?: (?! [\/][0-9]*% )\S )+
      )
   }sxg;

しかし、それは検証されません。検証したい場合は、使用できます

my @tokens;
push @tokens, $1
   while $line =~ m{
      \G
      ( \s+
      | ([\/])([0-9]*)%
        (?: (?! %\3\2 ). )*
        %\3\2
      | (?: (?! [\/][0-9]*% )\S )+
      | \z (*COMMIT) (*FAIL)
      | (?{ die "Syntax error" })
      )
   }sxg;

以下も検証しますが、もう少し読みやすく、トークンの種類を簡単に区別できます。

my @tokens;
for ($line) {
   m{\G ( \s+ ) }sxgc
      && do { push @tokens, $1; redo };

   m{\G ( ([\/])([0-9]*)%  (?: (?! %\3\2 ). )*  %\3\2 ) }sxgc
      && do { push @tokens, $1; redo };

   m{\G ( (?: (?! [\/][0-9]*% )\S )+ ) }sxgc
      && do { push @tokens, $1; redo };

   m{\G \z }sxgc
      && last;

   die "Syntax error";
}

posエラーが発生した場所に関する情報を取得します。

于 2013-03-18T08:59:31.897 に答える