テキストから任意の文字列を抽出する際における備忘録。
背景
筆者が設計ツールから出力されたテキストから特定の文字列抽出を行おうとした際に、
設計ツールのバージョン間で抽出対象のフォーマットに差異が生じていた。
そのため、フォーマットにある程度差異があっても期待した抽出が行えるような抽出方法を考察する。
考察方法
下記に示す条件で構成される文字列から果物の固有名詞のみを抽出する方法を考察する。
~条件~
1.文字列に日本語は登場しない。
2.文字列先頭には必ずFruitが記載される。
3.果物の名前は半角英数字及び空白の範囲で自由。
4.果物の後には空白と:の挿入が許される。
5.果物の後には空白の挿入が許される。
例を3つ、下記に記載する。
FruitApple
Fruit Ban ana
**Fruit:Mleon **
上記文字列から抽出する期待値はApple、Banana及びMelonである。
次節にて、テストパタン(文字列)を作成し、一通りの抽出方法で期待値を抽出する。
テストパタン作成
# -*- coding: utf-8 -*-
import re
test_str = []
test_str.append(r"FruitApple")
test_str.append(r"Fruit Banana")
test_str.append(r"Fruit Melon")
test_str.append(r"Fruit: Apple")
test_str.append(r"Fruit: Banana")
test_str.append(r"Fruit :Melon")
test_str.append(r"Fruit :Apple")
test_str.append(r"Fruit : Banana")
test_str.append(r"Fruit : Melon")
test_str.append(r"FruitApple ")
test_str.append(r"FruitBanana ")
test_str.append(r"Fruit M e l o n")
test_str.append(r"Fruit: : : : Apple")
test_str.append(r"Fruit : : : : Ba77 ") #とりあえず果物に数字を入れたく。
regex = r"^Fruit[: ]*(.+?) *$"
for i in test_str:
try:
print(re.search(regex,i, re.M).group(1).replace(' ',''))
except AttributeError:
print('Nothing')
実行
ragex.pyを実行する。
$ python3 ragex.py
Apple
Banana
Melon
Apple
Banana
Melon
Apple
Banana
Melon
Apple
Banana
Melon
Apple
Ba77
解説
正規表現である__regex = r"^Fruit[: ]*(.+?) $"__の考え方は以下の通り。
・Fruit後の*[: ]**は条件4の文字に対応。これにより、__(.+?)の文頭に空白及び:が混入しない。
・(.+?)は条件3に対応。果物名には空白も存在する可能性があるので、.__とした。
・末尾の __$"は条件5に対応。$を挿入しないと、文末の空白を認識することができず、(.+?)__の非貪欲マッチの結果、抽出される文字は一文字だけになってしまう。
上記の正規表現で文字列から果物名を抽出できるが、空白が存在する場合もあるので、__.replace(' ','')__を用いて抽出した果物名に含まれる空白を除外している。