0

次のファイルがあります。

id001   word1(100);"word2"(100);"word3"(98);"word4"(98);"word5"(94);word6;
id002   word1(100);word7(100);word8(100);word9(100);word10;word11;

ファイルの各行を分割して、id (=id00x)、val (=wordX)、および int (=100) を配列で取得します。私のコード:

my @fields = split /[\t();"]"?/, $line;
$id = $fields[0];
for ( my $i = 1; $i < @fields; $i +=2 )
{
  $val=$fields[$i];
  $int=$fields[$i+1]
}

二重引用符で囲まれていない id と val だけを取得します。

4

1 に答える 1

2

ここでの問題正規表現です。次のように、分割を行った直後にループを挿入することで、これを確認できます。

  my @fields = split /[\t();"]"?/, $line;
  $id = $fields[0];
  foreach my $field(@fields) {
    print("field is $field\n");
  }

これにより、空のフィールドがいくつかあることがわかります。そのため、変数に何も取得していません。空のフィールドの理由は、正規表現がリストされた文字のいずれか 1 つを単語境界として機能できるようにするためです。そのため、複数の文字を連続して使用すると、いくつかの連続した分割が発生します。

行全体を一度に分割しようとしないことで簡単になります。代わりに、行を小さな部分に分割することから始め、正規表現を使用して部分を抽出します。これが私の提案です:

my @fields = split /[\t;]/, $line;
$id = $fields[0];
for ( my $i = 1; $i < $#fields; $i++ )
  {
    ($val, $int) = $fields[$i] =~ /\"?(\w+)\"?\((\d+)\)/;
    print("val is $val, int is $int\n");
  }

また、配列内のオブジェクトの数を取得する方法は$#arraynameではなくであることに注意してください@arrayname。後者もスカラー コンテキストで機能しますが、これは悪い習慣です。


以下は元の回答です。これは構文に関するものでした

少なくとも 1 つのエラーがあります。

$val=$fields[i];
$int=$fields[i+1]

次のよう$に、の前にも使用する必要があります。i

$val=$fields[$i];
$int=$fields[$i+1]
于 2013-03-19T12:27:59.617 に答える