あなたが持っている:
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 つ以上の単語文字が続く限り、一致があり、 $1
andが設定されます。$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.