2016-06-14 20 views
1

perlで正規表現のグループ化に問題があります。perl正規表現の文字クラス

もちろん、これははるかに大きな問題ですが、それは私が扱っているのと同じ概念です。皆さんのコメントやアイデアを事前にお寄せいただきありがとうございます。

以下の正規表現は、文字列のこの部分のみを意識して決定する必要があります。

doctor_who:EE

doctor_who:EP

doctor_who:元

なくは

doctor_who:ええ

コード:

$str = "doctor_who:ee123ABC451234.123"; #match 
$str = "doctor_who:ep123YXZ451234.123"; #match 
$str = "doctor_who:ex123451234.123"; #match 
$str = "doctor_who:eeh1234LMNOP51234.123"; ##should not match 
$str = "doctor_who:abc12341234.123"; ##should not match 

$regex = "doctor_who:e[e|p|x]"; #--->problem, what to add/remove? 

if ($str =~ m/$regex/){ 
    print "match!"; 
} 
else { 
    print "not matched\n"; 
} 
+0

/doctor_who:e(?:[px]|e[^h])/ 
注: '[E | P | X]' [EPX |] 'と同じものです'。それらの4文字のいずれかに一致します。あなたは '[epx]'を使うつもりです。 – ikegami

答えて

2

負の先読みゼロ幅アサーションでは簡単です。これは、具体的一致したくないだけの事はあるdoctor_who:eeh*前提としています。上記の例で

/doctor_who:e(?!eh)[epx]/ 

は、限り、我々は doctor_who:eに一致するように、我々はすべての試合に先読みをトリガします。 :後の第2のcharない限り先読みを先送りにされ何それはやる

/doctor_who:e(?:[px]|e(?!h))/ 

pxではありません。@ikegamiによってコメントで述べたように我々は、絶対に必要な場合にのみ、それを使用することによって効率を得ることができますその文字がeの場合のみ

全く前後参照を使用していないコメントに示す第2の例:

+1

見た目は高価なので、' '/ doctor_who:e(?:[px] | e(?!h))/'や '/ doctor_who:e(? [px] | e(?:[^ h] | \ z))/ '。実際には、 '(?:[^ h] | \ z)'の代わりに '[^ h]'を使うことができます。 – ikegami

+0

オハイオ州、それは良いです@池上、ありがとう! – stevieb

1

あなたは私はあなたが2つの正規表現が必要だと思う文字列の末尾に一致していませんので。

$regex = "doctor_who:e[epx]"; # match 
$not_regex "doctor_who:e[epx][a-z]"; #-do not match 

それからちょうど

if($string =~ $regex and $string !~ $not_regex){} 
+0

彼は文字列の最後に一致を試みていません。それは決して一致しません – stevieb

+0

私は今それが動作するはずだと思う。 – cberning

1

を行うあなたは、この2つの方法で行うことができますし、両者を組み合わせました。これらは正の試合を提供し、彼らはeeh試合を拒否するように何かを必要とする

$regex = 'doctor_who:e(e|p|x)'; 

$regex = 'doctor_who:e[epx]'; 

が交互に使用します。

は、文字クラスを使用します。

ただし、eehと一致するのは一致しますか?あなたが言及した唯一のものですが、より一般的なもの、例えばa-zのようなものを好むでしょうか? (例)eecはどうですか?一致するか拒否されるべきですか?

例から、ee1が一致します。それは1ではなく、hでないか、それとも数字なのですか?

例にいくつかの抜け穴があるので、[最高、最も簡潔な正規表現がすべきであることは完全にはっきりしません。だから、あなたが本当に好きなものについて私が作った前提に基づいて、いくつかの正規表現があります。だから、

eehが唯一の拒絶であれば、追加します。

$regex .= '[^h]'; 

を使用すると、より広範な拒否たい場合:

$regex .= '[^a-z]'; 

または、おそらくを、あなただけに一致したいと思います数値:

$regex .= '[0-9]'; 

サイドノート:この答えは持っています以下のコメントを反映するように編集されました

+0

OPは文字列の最後に一致を試みていません。このようにする場合は、特定の長さの文字列をsubstrするか、必要な部分だけを抽出して、$ – stevieb

+0

と一致する文字列を作成する必要があります。単語の境界は空白で、ヒットしようとした後に空白はありません:) – stevieb

+0

@steviebありがとう。私はそれに応じて編集しました –

関連する問題