あなたが持っている:
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.