まあ...これはあなたが尋ねたことです。しかし、それは非常に醜い、あなたが提供した例に非常に特有です。私はそれが実際のデータファイルに対して失敗すると思う。
この種の解析ジョブに直面すると、問題を解決する方法の1つは、いくつかの予備的なクリーンアップによって入力データを実行し、可能であればテキストを単純化し合理化することです。たとえば、整数のリストの異なるフレーバーを扱うことは迷惑であり、正規表現はより複雑になります。不必要なカンマの間のコンマを削除して、ターミナル「or-and」を削除できれば、正規表現ははるかに簡単になります。そのようなクリーンアップが完了したら、必要なビットを抽出するために1つ以上の正規表現を適用することができます。場合によっては、主要な正規表現を満たさないアウトライヤーの数は、特定のルックアップまたはハードコードされた特別なケースのルールで処理できます。
import re
lines = [
"if magic code is 543, and type is 5642, 912342, or 7425, type has to have a period. EX: 02-15-99",
"If Magic Code is 722, 43, or 643256 and types is 43234, 5356, and 2112, type has to start with period.",
"if magic code is 4542 it is not valid in type.",
"if magic code is 532 and date is within 10 years from current data, and the type is 43, the type must begin with law number.",
]
mcs_rgx = re.compile(r'magic code is (\d+ (or|and) \d+|\d+(, \d+)*,? (or|and) \d+|\d+)', re.IGNORECASE)
types_rgx = re.compile(r'types? is (\d+ (or|and) \d+|\d+(, \d+)*,? (or|and) \d+|\d+)', re.IGNORECASE)
rest_rgx1 = re.compile(r'(type (has|must).+)')
rest_rgx2 = re.compile(r'.+\d(.+)')
nums_rgx = re.compile(r'\d+')
for line in lines:
m = mcs_rgx.search(line)
if m:
mcs_text = m.group(1)
mcs = map(int, nums_rgx.findall(mcs_text))
else:
mcs = []
m = types_rgx.search(line)
if m:
types_text = m.group(1)
types = map(int, nums_rgx.findall(types_text))
else:
types = []
m = rest_rgx1.search(line)
if m:
rest = [m.group(1)]
else:
m = rest_rgx2.search(line)
if m:
rest = [m.group(1)]
else:
rest = ['']
print mcs, types, rest
出力:
[543] [5642, 912342, 7425] ['type has to have a period. EX: 02-15-99']
[722, 43, 643256] [43234, 5356, 2112] ['type has to start with period.']
[4542] [] [' it is not valid in type.']
[532] [43] ['type must begin with law number.']
出典
2016-11-24 03:14:20
FMc
あなたがつかむために探している文字列の部分とのルールは何ですか? – idjaw
私が望む結果は投稿にあります。 –
*テキストにバリエーションがたくさんあります。* - 自然言語の認識が必要で、正規表現は必要ないようです。どのように@Lukeallthingsspatial –