言葉

2012-05-01 18 views
4

私のような単語のリスト持っているのリストの中から単語のペアを見つけるために正規表現を使用して:、私はこのリストの中から単語のペアを見つけたい言葉

l = """abc 
dfg 
hij 
jih 
gfd 
cba 
cbd 
jip 
gfe 
jiw 
cbw""" 

をので、最初の単語がされ :

.(.)(.) 

そして、2番目の単語は、次のとおりです。

\2\1. 

だから、\ 1、\ 2は、最初のワット内の文字を参照してください。 ord。 (... findAllのが唯一の非重複の結果を返すため)

re.findall('(^.(?P<A>.)(?P<B>.)$)(?=.*(^(?P=B)(?P=A).$))', l, re.DOTALL | re.MULTILINE) 

しかし、この検索は、ペアの一部だけを返します。私が思い付くことができ

最高の正規表現です。 次に、正のlookbehindアサーションを使用することを考えましたが、固定長の文字列でのみ使用できます。

正規表現でこれを行う方法はありますか?

+0

例だけではなく、単語のペアの関係を単語で説明できますか?私はあなたがある精度を失ったかもしれないと思う。図のように、言葉は常に正確に3文字の長さですか? –

+0

サンプルデータでは、 'abc'は' cba'、 'cbd'、または' cbw'と対になります。あなたは好みがありますか?あるいは、それらのすべてを手に入れたいですか? –

+0

@Alan:明らかに、彼はそれらのすべてを手に入れたいと思います。そうしないと、正規表現のアプローチが有効になります。 –

答えて

2

私は、正規表現がこれを行う良い方法だとは思っていません(特にPythonでは、単にPerlのような文字列をマッチングさせるための方法をすべて得ることができなかったので、すべてのプレフィックスに対してfindallあなたの文字列の)。簡単な選択肢は次のようになります。あなたはまた、最初のパスで辞書に単語の接頭辞を保存することで、本当に速いこの問題を解決して、関連付けを構築することができ

>>> map(tuple, pairs) 
[('hij', 'jip'), 
('abc', 'cbd'), 
('dfg', 'gfd'), 
('dfg', 'gfe'), 
('jiw', 'hij'), 
('hij', 'jih'), 
('abc', 'cbw'), 
('abc', 'cba')] 

:中

words = l.split() 
pairs = set(frozenset((w1, w2)) for w1 in words for w2 in words 
         if w1[1:] == w2[1::-1]) 

結果

from collections import defaultdict 

prefixes = defaultdict(list) 
for w in words: 
    prefixes[w[1::-1]].append(w) 
pairs = set(frozenset((w1, w2)) for w1 in words for w2 in prefixes[w1[1:]]) 

これは、正規表現エンジンではパフォーマンスが低下する可能性があります。

+0

私は非常に長い単語リストを持っていると仮定して、正規表現を使用していないのです(もし可能なら...)。 – ItaiS

+0

@ItaiS:ルックアップ辞書の解決策はO(n)です。正規表現エンジンが作成するNFAの種類は、問題のセマンティクスについて何も知らないため、2次ランタイムを持つことになります。ベンチマークしましたか? –