12

Python 2.7.2 スクリプトを使用して、マスター単語リストとして使用しているテキスト ファイル内の単語のリストを検索しています。

ターミナル ウィンドウでスクリプトを呼び出し、任意の数の正規表現を入力して、スクリプトを実行しています。

したがって、2 つの正規表現 "^.....$" と ".*z" を渡すと、少なくとも 1 つの "z" を含む 5 文字の単語がすべて出力されます。

私がやろうとしているのは、別の正規表現を追加して、文字列から文字を除外することです。「y」ではなく「z」の 5 文字を含むすべての単語を出力したいと思います。

コードは次のとおりです。

import re
import sys

def read_file_to_set(filename):
    words = None
    with open(filename) as f:
        words = [word.lower() for word in f.readlines()]
    return set(words)

def matches_all(word, regexes):
    for regex in regexes:
        if not regex.search(word):
            return False
    return True

if len(sys.argv) < 3:
    print "Needs a source dictionary and a series of regular expressions"
else:
    source = read_file_to_set(sys.argv[1])
    regexes = [re.compile(arg, re.IGNORECASE)
               for arg in sys.argv[2:]]
    for word in sorted(source):
        if matches_all(word.rstrip(), regexes):
            print word,

プログラムが出力する文字列から特定の文字を除外できるようにするために、プログラムに渡す正規表現にどの修飾子を追加できますか?

それが不可能な場合、コードに何を実装する必要がありますか?

4

2 に答える 2

28

一致しない文字を指定するには、次のようにします (これは小文字以外のすべてに一致します)。

[^a-z]

したがって、「y」を含まない文字列に一致させるための正規表現は次のとおりです。^[^y]*$

文字ごとの説明:

^正規表現の開始時に来る場合、「開始」を意味します。同様に、$最後に来る場合は「終わり」を意味します。 [abAB]または範囲内の任意の文字に一致します。たとえば、任意の 16 進文字 (大文字または小文字) に一致します。[a-fA-F0-9]

*は、前の式の 0 個以上を意味します。内の最初の文字である[],^には別の意味があります。つまり、「ない」という意味です。したがって[^a-fA-F0-9]、16 進数以外の任意の文字に一致します。

との間にパターンを配置する^$、正規表現が文字列と正確に一致するように強制されます (パターンの前後には何もありません)。これらすべての事実を組み合わせてください。

^[^y]*$'y' 以外の 0 文字以上の文字列を意味します。(もっと面白いことをするために、数字以外をチェックすることができます:^[^0-9]$

于 2013-11-12T09:06:23.193 に答える
10

でこれを実現できますnegative look arounds。これは正規表現が特に高速なタスクではありませんが、機能します。sub-string を除くすべてに一致さfooせるには、次を使用できます。

>>> my_regex = re.compile(r'^((?!foo).)*$', flags = re.I)
>>> print my_regex.match(u'IMatchJustFine')
<_sre.SRE_Match object at 0x1034ea738>
>>> print my_regex.match(u'IMatchFooFine')
None

他の人が指摘したように、単一の文字のみを照合する場合は、単純な not で十分です。より長く複雑なネガティブ マッチでは、このアプローチを使用する必要があります。

于 2013-11-12T09:18:15.693 に答える