2017-06-26 4 views
0

文字列を複数のパターンと照合し、その配列を配列に格納しようとしています。複数のパターンを取得する

入力は、次のいずれかになります。

-fnospacebetween 
    -f textwithspacebefore 
@nospacebetween 
    @ textwithspacebefore 

正規表現は-fまたは@後の文字列をキャッチする必要があります。スペースは、-f@の前に、また-fまたは@と文字列の間で使用できます。
私は|分割正規表現を使用することを考えましたが、特定の順序で2つの正規表現を使用すると、なぜ私の入力をキャッチしないのか分かりません。
単一の場合のシナリオ、期待通りに動作します:

my $text = '@anystring' ; 

if($text =~ /^\s*\@\s*(\S*)/) 
{ 
    print "\n $1"; 
} 



my $text = '-fanystring' ; 

if($text =~ /^\s*-f\s*(\S*)/) 
{ 
    print "\n $1"; 
} 

しかし、私は2つのいずれかでの単一の正規表現を使用しようとすると、私はUse of unitialized...を得る:

my $text = '@anystring' ; 

if($text =~ /^\s*-f\s*(\S*)|^\s*\@\s*(\S*)/) 
{ 
    print "\n $1"; 
} 

しかし、この変形と、それが正常に動作します:

my $text = '@anystring' ; 
if($text =~ /^\s*\@\s*(\S*)|^\s*-f\s*(\S*)/) 
{ 
    print "\n1: $1"; 
} 

注文が切り替わると、正しく一致するのはなぜですか?

+0

@Borodin、ごめんなさい、最初の2つの例だけに '-'を付けるべきです –

+1

もう一つの解決策は、ブランチリセットを使うことです:' /(?\\ s * \ @ \ s * S *)|^\ s * -f \ s *(\ S *))/ 'パターンが完全に異なっていて、ボロディンの答えのようにそれらを「契約」することはできません。 –

答えて

1

注文が切り替わると、正しく一致するのはなぜですか?

この正規表現

/^\s*\@\s*(\S*)|^\s*-f\s*(\S*)/ 

は代替一致に応じて、$1または$2いずれかにキャプチャします。しかし、あなたは今までそれが唯一のキャプチャを持ち、変数

あるパターンの一部のみに交代を使用しています、私はあなたの代わりにこれを使用することをお勧め

にマッチした第二の代替であった場合undefである、$1を印刷します

/^\s*(?:\@|-f)\s*(\S*)/ 
+0

ああ、私はそれが '$ 1'の両方からのグループ化を保存すると仮定しました。提案していただきありがとうございます。私のソリューションは '$ 1'と' $ 2'の追加チェックが必要なので、私はこれを使用します。 –

+0

このケースが文書化されている場所をご存知ですか? –

+0

@ジョンドー:申し訳ありません、どのような場合? – Borodin

0

あなたの正規表現で別の潜在的な問題には、引数GIVが存在しない場合、それはまたある

-f -fanother-flag 
[email protected] [email protected] 

は、\S*は、任意の以下のフラグが一致すると一致するということです最初の旗に。引き数がオプションの場合は\s*([^-]?\S*)を使用するほうがよく、必須の場合は\s*([^-]\S*)を使用することをお勧めします。これは、引き続きflag引数がハイフンで始めることができないことを前提としています。

関連する問題