0

次の形式の文字列があります

some_string = ",,, xxx ,,, xxx ,,, xxx ,,, xxx ,,, xxx ,,,xxx,,,"これはfというテキストファイルの内容です

xxx内の特定の用語を検索したい(その用語が「シリコン」であるとしましょう)

xxxはすべて異なる可能性があり、改行を除く任意の特殊文字(メタ文字を含む)を含めることができることに注意してください

match = re.findall(r",{3}(.*?silicon.*?),{3}", f.read())
print match

しかし、これは次の形式の結果を返すため、機能していないようです:["xxx ,,, xxx ,,, xxx ,,, xxx ,,,silicon"、 "xxx ,,, xxx ,,, xxx、 ,, xxsiliconxx "]しかし、私はそれを返すだけにしたい["silicon "、" xxsiliconxx "]

私は何が間違っているのですか?

4

1 に答える 1

1

次の正規表現を試してください。

(?<=,{3})(?:(?!,{3}).)*?silicon.*?(?=,{3})

例:

>>> s = ',,,xxx,,,silicon,,,xxx,,,xxsiliconxx,,,xxx'
>>> re.findall(r'(?<=,{3})(?:(?!,{3}).)*?silicon.*?(?=,{3})', s)
['silicon', 'xxsiliconxx']

xxxのコンテンツには、 3つの連続するコンマではなく、コンマを含めることができると想定しています。そうしないと、フィールドが終了します。セクションのコンテンツにxxxコンマを含めることができない場合は、代わりに次を使用できます。

(?<=,{3})[^,\r\n]*?silicon.*?(?=,{3})

現在のアプローチが機能しない理由は、.*?可能な限り少ない文字を一致させようとしても、一致は可能な限り早く開始されるためです。したがって、たとえば、正規表現a*?bは文字列全体と一致します"aaaab"。正規表現が開始位置を進めるのは、正規表現が一致しない場合のみです。また、,,,で一致させることができるため.*?、一致は常に文字列の先頭または前の一致の直後に開始されます。

後読みと先読みは、コメントでJaredCによって提起された問題に対処するために使用され、基本的re.findall()に重複する一致を返さないため、先頭と末尾が一致に含ま,,,れないようにする必要があります。

于 2013-01-10T01:46:47.047 に答える