2

私は初心者で、最初のプログラミング言語として数か月間 Python を学んでいます。テキストファイルからパターンを探しています。私の最初の試みは正規表現を使用していました。これは機能しますが、制限があります。

import re

noun_list = ['bacon', 'cheese', 'eggs', 'milk', 'list', 'dog']
CC_list = ['and', 'or']

noun_list_pattern1 = r'\b\w+\b,\s\b\w+\b,\sand\s\b\w+\b|\b\w+\b,\s\b\w+\b,\sor\s\b\w+\b|\b\w+\b,\s\b\w+\b\sand\s\b\w+\b|\b\w+\b,\s\b\w+\b,\saor\s\b\w+\b'

with open('test_sentence.txt', 'r') as input_f:
    read_input = input_f.read()
    word = re.findall(noun_list_pattern1, read_input)
    for w in word:
        print w
else:
    pass

したがって、この時点で、リストが使用されていないのに、なぜこのコードにリストがあるのか​​と疑問に思うかもしれません。さて、私は頭を悩ませ、あらゆる種類の for ループと関数内の if ステートメントを試して、正規表現パターンを複製する理由を見つけようとしましたが、リストを使用しました。

正規表現の制限は\b\w+\w\、`noun_list_pattern' で何度も見つかったコードが、実際には単語 (任意の単語) のみを検出し、特定の名詞を検出しないことです。これにより、誤検知が発生する可能性があります。正規表現の代わりに上記のリストの要素を使用して、さらに絞り込みたいと思います。

実際には正規表現パターンに 4 つの異なる正規表現があるため (4 が含まれています|)、ここではそのうちの 1 つを使用します。したがって、次のようなパターンを見つける必要があります。

'noun in noun_list' + ', ' + 'noun in noun_list' + ', ' + 'C in CC_list' + ' ' + 'noun in noun_list

明らかに、上記のコードで引用された行は実際の python コードではありませんが、必要な一致についての私の考えを表現したものです。私が言うところではnoun in noun_list、noun_list の繰り返しを意味します。C in CC_listCC_list の繰り返しです。,コンマと空白に一致するリテラル文字列です。

うまくいけば、私は自分自身を明確にしました!

test_sentence.txt私が使用しているファイルの内容は次のとおりです。

I need to buy are bacon, cheese and eggs. 
I also need to buy milk, cheese, and bacon.
What's your favorite: milk, cheese or eggs.
What's my favorite: milk, bacon, or eggs.
4

2 に答える 2

2

実際には、元のリストだけを使用してこれを行う方法がいくつかあるため、正規表現は必ずしも必要ではありません。

noun_list = ['bacon', 'cheese', 'eggs', 'milk', 'list', 'dog']
conjunctions = ['and', 'or']

#This assumes that file has been read into a list of newline delimited lines called `rawlines`
for line in rawlines:
    matches = [noun for noun in noun_list if noun in line] + [conj for conj in conjunctions if conj in line]
    if len(matches) == 4:
        for match in matches:
            print match

マッチ数が 4 なのは、4 が正しいマッチ数だからです。(これは、繰り返される名詞または接続詞の場合にも当てはまることに注意してください)。

編集:

このバージョンは、一致した行と一致した単語を出力します。また、複数の単語が一致する可能性がある問題も修正されました。

words_matched = []
matching_lines = []

for l in lst:
    matches = [noun for noun in noun_list if noun in l] + [conj for conj in conjunctions if conj in l]
    invalid = True
    valid_count = 0
    for match in matches:
        if matches.count(match) == 1:
            valid_count += 1
    if valid_count == len(matches):
        invalid = False

    if not invalid:
        words_matched.append(matches)
        matching_lines.append(l)

for line, matches in zip(matching_lines, words_matched):
    print line, matches

itertoolsただし、これが気に入らない場合は、いつでも次のように (モジュールを使用して) 正規表現を作成できます。

#The number of permutations choices is 3 (as revealed from your examples)
for nouns, conj in itertools.product(itertools.permutations(noun_list, 3), conjunctions):
    matches = [noun for noun in nouns]
    matches.append(conj)
    #matches[:2] is the sublist containing the first 2 items, -1 is the last element, and matches[2:-1] is the element before the last element (if the number of nouns were more than 3, this would be the elements between the 2nd and last).
    regex_string = '\s,\s'.join(matches[:2]) + '\s' + matches[-1] + '\s' + '\s,\s'.join(matches[2:-1])
    print regex_string
    #... do regex related matching here

このメソッドの注意点は、両方のリストのすべての可能な組み合わせ (順列の読み取り) を生成するため、純粋に力ずくであるということです。これをテストして、各行が一致するかどうかを確認できます。したがって、非常に遅いですが、指定されたもの (接続詞の前の非カンマ) に一致するこの例では、完全に完全に一致します。

必要に応じて調整します。

于 2013-09-22T05:19:13.277 に答える