複数の行にまたがるファイルの一部を検出したい場合、およびファイルがそれほど巨大でない場合、一度に 1 行ずつ調べることによって正規表現の能力を制限するのは特に良い方法ではありません。ファイルを読み取って全体を RAM に配置できる場合は、テキストを一意の全体として探索する正規表現を使用して分析することをお勧めします。
フラグが使用されていない場合は「文字列の先頭」、このフラグが使用されている場合は「行の先頭」'^'
に意味があることに注意してください。re.MULTILINE
ちなみに、この方法を使えばREパターンの先頭match()
に追加する必要はありません。文字列の先頭からマッチさせようとするからです。"^"
match()
したがって、ここでは、必要に応じてテキスト全体を分析する方法を示します (splitlines(True)
文字列ss内の行のリストを取得するために使用します。このリストはファイルをシミュレートします° :
import re
ss = """ first line
bli bli hhhhhhhh TEXT bla blajjjjjjjjj
hhhhhhhh VVVVV
ZZZZZZ
tttt
bolo bolo TEXTrumunu and badad
yyyyyyyyyyyyyyyy
kkkkkkkkkkk
jjjjjjjjjjjjjjj
nnnn uytr
poiurrr
ahahahah bobobo
ppppp TEXT aaaabbbbb cccccg
kmsms
TEXT fedex redex bidex
pududadi
A
no-whitespace-before-that
hhrhezipo"""
regx = re.compile('TEXT *(.+(?<! )(?<!\r)(?:\n[^ ]+(?<!\n))?)')
for fnd in regx.findall(ss):
print '\n'.join(map(repr,fnd.splitlines(True)))
print '---------------------------------'
結果:
'bla blajjjjjjjjj\n'
'hhhhhhhh'
---------------------------------
'rumunu and badad\n'
'yyyyyyyyyyyyyyyy\n'
'kkkkkkkkkkk\n'
'jjjjjjjjjjjjjjj'
---------------------------------
'aaaabbbbb cccccg'
---------------------------------
'fedex redex bidex\n'
'pududadi\n'
'A\n'
'\n'
'no-whitespace-before-that'
---------------------------------
.
ファイルが巨大で、RAM の 1 つのチャンクだけで充電できない場合は、次のようにできます。
import re
ss = """ first line
bli bli hhhhhhhh TEXT bla blajjjjjjjjj
hhhhhhhh VVVVV
ZZZZZZ
tttt
bolo bolo TEXTrumunu and badad
yyyyyyyyyyyyyyyy
kkkkkkkkkkk
jjjjjjjjjjjjjjj
nnnn uytr
poiurrr
ahahahah bobobo
ppppp TEXT aaaabbbbb cccccg
kmsms
TEXT fedex redex bidex
pududadi
A
no-whitespace-before-that
hhrhezipo"""
rigx = re.compile('TEXT *(.+\n?)')
li = []
for line in ss.splitlines(True):
mat = rigx.search(line)
if 'TEXT' in line:
li.append(mat.group(1))
elif ' ' in line and li:
if not line.startswith(' '):
li.append(line.split(' ')[0])
li[-1] = li[-1].rstrip(' \r\n')
print '\n'.join(map(repr,li))
print '====================='
li = []
elif li:
li.append(line)
このコードは、前のコードと同じ結果になります。それほど単純ではないことがわかります。これは、大きなファイルほど問題が発生しやすいためです。