2012-03-18 2 views
-1

私はパズルを解くアプリケーションをPythonで書いています。私はいくつかの文字の組み合わせを探していますが、文字セット[abcd]があれば、abcdという文字だけを含むテキストの中にサブ文字列を見つける必要があります。文字abcdはdcbaまたはabbcddと一致しますが、acd、bbcdまたはabcedは一致しません。正規表現[abcd] +を使用すると、各文字が含まれていない部分文字列が得られます正規表現は少なくとも一度は各文字に一致します

+6

あなたはPythonのタグを追加する必要があります。あなたはまた、あなたがすでに試したことを示し、何がうまくいかないかを説明する必要があります。これはGIMME DA CODEサイトではありません。 – tchrist

+0

詳細を教えてください。これはあまりにも曖昧です。 –

答えて

4

なぜ正規表現を使用しますか?

def hasChars(search_string, chars): 
    return all(x in search_string for x in chars) 

>>> hasChars('aaabcd', 'abc') 
True 
2

文字列は、少なくともABCD含まれている必要がありますが、他の人を含めることができる場合だけでなく、彼らは唯一のABCD含めることができ、場合、これは

(?=.*a)(?=.*b)(?=.*c)(?=.*d)

を働くだろう、これはおそらく

優れています

^(?=.*a)(?=.*b)(?=.*c)(?=.*d)[abcd]+$

更新

あなたは、フローティングバージョンを探している場合は、質問に答えるために、これはあなたが欲しいものを行います。

(?=([abcd]{4,}))(?=[bcd]*a)(?=[acd]*b)(?=[abd]*c)(?=[abc]*d)\1

が拡張:

 # At POSition 
(?=    # Lookahead 
    (     # Capture grp 1 
     [abcd]{4,}   # Get 4 or more (greedy) 'a' or 'b' or 'c' or 'd' characters 
    ) 
) 
(?=    # Lookahead, check for 'a' (still at POS) 
    [bcd]*a    # 0 or more [bcd]'s then 'a' 
) 
(?=    # Lookahead, check for 'b' (still at POS) 
    [acd]*b    # 0 or more [acd]'s then 'b' 
) 
(?=    # Lookahead, check for 'c' (still at POS) 
    [abd]*c    # 0 or more [abd]'s then 'c' 
) 
(?=    # Lookahead, check for 'd' (still at POS) 
    [abc]*d    # 0 or more [abc]'s then 'd' 
) 
\1     # Backref to capt grp 1, consume it 

    # Passed test, now at POSition + length of capture group 1 

より

ます検索文字列から正規表現を体系的に構築できるかもしれません。私はよくそのpythonを知らないので、ここではPerlでそれを行う方法のサンプルです。文字列が長ければ長いほど、マッチを見つけるのに時間がかかるが、これはかなり速くなるはずであることに注意してください。

use strict; 
use warnings; 

my $samp = 'bddaaabcabbad characters abcd matches dcba or abbcdd, but not acd, bbcd or abced'; 

my $regex = '(?=([abcd]{4,}))(?=[bcd]*a)(?=[acd]*b)(?=[abd]*c)(?=[abc]*d)\1'; 

while ($samp =~/$regex/xg) 
{ 
    print "Found '$1'\n"; 
} 

# Regex construction 
# ------------------------------ 
my @AryofSearchStrs = (
'abcd', 
'%^&*', 
'hi()there', 
'==-yes', 
); 

for my $search_string (@AryofSearchStrs) 
{ 
    my $str = $search_string; 
    while($str =~ s/(.)(.*)\1/$1$2/g) {} 

    my @astr = split '', $str; 

    my $rxformed = '(?=([' . quotemeta($str) . ']{' . length($str) . ',}))'; 
    for (my $i = 0; $i < @astr; $i++) 
    { 
     $rxformed .= 
     '(?=[' 
     . join('', map { quotemeta($_) } @astr[0..($i-1), ($i+1)..$#astr]) 
     . ']*' 
     . quotemeta($astr[$i]) 
     . ')'; 
    } 
    $rxformed .= '\1'; 

    print "\n\n============\n"; 
    print "Search string = '$search_string'\n"; 
    print "Normalized = '$str'\n"; 
    print "Formed regex = \n$rxformed\n"; 
} 

出力は

Found 'bddaaabcabbad' 
Found 'abcd' 
Found 'dcba' 
Found 'abbcdd' 


============ 
Search string = 'abcd' 
Normalized = 'abcd' 
Formed regex = 
(?=([abcd]{4,}))(?=[bcd]*a)(?=[acd]*b)(?=[abd]*c)(?=[abc]*d)\1 


============ 
Search string = '%^&*' 
Normalized = '%^&*' 
Formed regex = 
(?=([\%\^\&\*]{4,}))(?=[\^\&\*]*\%)(?=[\%\&\*]*\^)(?=[\%\^\*]*\&)(?=[\%\^\&]*\*)\1 


============ 
Search string = 'hi()there' 
Normalized = 'hi()ter' 
Formed regex = 
(?=([hi\(\ \)ter]{8,}))(?=[i\(\ \)ter]*h)(?=[h\(\ \)ter]*i)(?=[hi\ \)ter]*\()(?=[hi\(\)ter]*\)(?=[hi\(\ ter]*\))(?=[hi\(\ \)er]*t)(?=[hi\(\ \)tr]*e)(?=[hi\(\ \)te]*r)\1 


============ 
Search string = '==-yes' 
Normalized = '=-yes' 
Formed regex = 
(?=([\=\-yes]{5,}))(?=[\-yes]*\=)(?=[\=yes]*\-)(?=[\=\-es]*y)(?=[\=\-ys]*e)(?=[\=\-ye]*s)\1 
+0

ありがとう!後者の方法では文字列全体を一致させることができますが、実際には文字列を文字列内の部分文字列として実際に探す必要があります。私は実際に上記の方法がどのように機能するのかわからないので、それから作業するのに問題があります。私は上記の構文要素をカバーする正規表現のチュートリアルを終えましたが、この文脈でどのように使われているのか分かりません。これを理解する正しい方向のどの点でも大いに感謝します。 –

+0

@python whisperer - 必要な部分文字列を得るための正規表現と説明を追加しました。いつものように、あなたがこれらの有用なものを見つけたら、アップアップして回答を受け入れてください(あなたがまだできたら)。 – sln

関連する問題