2

次のコードがあります。

my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ m/^(\w)*\:(\w*)\_em\.$/)
{
    print "$1\:$2\.\n";
}
else
{
    print "$1\:$2\_em\.\n";
}

しかし、私は空になりつつ$1あり$2ます。出力は次のとおりです。

Use of uninitialized value in concatenation (.) or string at new_mscn_iden_parse.pl line 187.
Use of uninitialized value in concatenation (.) or string at new_mscn_iden_parse.pl line 187.
:_em.
4

3 に答える 3

4

このコードはあなたが望むことをします

my $sDatabase = "abc_def:xyz_comp.";

$sDatabase =~ m/^(\w+):(\w+?)(_em)?\.$/ or die "Invalid data";
if ($3) {
  print "$1:$2.\n";
}
else {
  print "$1:$2_em.\n";
}
于 2013-04-29T19:26:34.650 に答える
3

一致しない場合、何を期待$1$2、含める必要がありますか?!

一致を試みる前に含まれていたものがすべて含まれています。

考えられる解決策:

$sDatabase =~ s/(?<!_em)(?=\.\z)/_em/;
于 2013-04-29T19:11:52.047 に答える
1

あなたが持っている:

my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ m/^(\w)*\:(\w*)\_em\.$/);

これが一致するかどうか見てみましょう:

あなたは正規表現です:

  • 行の先頭にアンカーします。
  • ゼロ個以上の単語文字を探しています。単語の文字 (ASCII アルファベット) には、小文字、大文字、数字、およびアンダースコアが含まれます。
    • したがって/\w*/、次のすべてに一致します。
    • コンピューター
    • コンピューター
    • コンピューター23
    • コンピューター_32
    • 空の文字列
  • 次はコロンを探します
  • 次に、さらに単語の文字
  • _em文字列が続く
  • ピリオドが続く
  • そして、それは文字列の最後である必要があります (NL がなく、複数行の文字列検索を行っていない場合。安全に見えます)。

次に、文字列を見てみましょう。abc_def:xyz_comp.

  • \w*まで一致しabc_defます。正規表現は貪欲で、可能な限り文字列の最大部分に一致させようとします。
  • :コロンに一致します。これまでのところ、一致していますabc_def:
  • に一致\w*xyz_compます。
  • 今、あなたは a をマッチさせようとしています_em。おっとっと!ダメ。あなたの文字列にはありません_em。正規表現の一致は失敗します。

正規表現の一致が失敗するため、変数$1$2変数は設定されておらず、値がありません。

それがあなたが得ている理由ですUse of uninitialized value。できることは、式の後半をオプションにすることです。

my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ /^(\w)+:(\w*)(_em)?\.$/) {
    if ( $3 ) {
        print "$1:${2}${3}.\n";
    else {
        print "$1:${2}_em.";
    }
}
else {
   die qq(String doesn't match regular expression at all\n);
}

}

まず、少なくとも1文字は一致させたいと思います (私が間違っている可能性があります)。そのため、0 個以上に一致するアスタリスクを+1 個以上に一致する a に切り替えました。

3 番目の括弧の後に . があることに注意してください?。これは、これを0 回または 1回一致させることを意味します。したがって、文字列が 1 つ以上の単語文字で始まり、その後にコロンが続き、その後に 1 つ以上の単語文字が続く限り、一致があり、 $1andが設定されます。$2

必ずしも起こるとは限らないのは、それ$3が設定されるということです。これは、文字列も で終わる場合にのみ設定されます_em.。文字列に , が含まれていなくても_em、ピリオドで終わっていて$1$2一致する場合。

あなたの場合、これを行うことで簡単にすることができます:

my $sDatabase = "abc_def:xyz_comp.";
if ($sDatabase =~ /^(\w)+:(\w*)(?:_em)?\.$/) {
    print "$1:${2}_em.";
else {
   die qq(String doesn't match regular expression at all\n);
}

(?:...)手段は一致を設定せず、グループ化するだけです。したがって、$3設定されることはありません。大丈夫です。$3 を使うか、マッチの最後に_em.追加します。_em.

于 2013-04-29T21:32:32.817 に答える