クレームツリーを何とかする(その2)
前回の投稿(クレームツリーを何とかする(その1))で紹介したプログラムでは請求項が記載されたファイル(meisai.txt)における請求項の記載が「請求項nまたはm」や「請求項nないしm」といった記載ではうまく動作しないので、meisai.txtを書き換えるプログラムを作成してみました。
クレームツリーを何とかする(その1)のプログラムを実行する直前に以下のprogram1を実行ください。
import re
import shutil
import unicodedata
#part1 前処理
shutil.copy("meisai.txt","meisai_bk.txt")
meisai = []
ms_base = []
f = open('meisai.txt', 'r')#ANSIで保存すること
ms_base = f.read()
f.close()
ms_base=unicodedata.normalize("NFKC", ms_base)#請求項数の数値を半角にする
meisai = re.split("【",ms_base)#請求項ごとに分割する
meisai.pop(0)
meisai2=[]
#part2 「または」処理
pattern = r"請求項(\d+)または(\d+)"
replacement = r"請求項\1または請求項\2"
for ms_part in meisai:
new_text = re.sub(pattern, replacement, ms_part)
new_text = new_text.rstrip("\n")#文末改行を削除
meisai2.append(new_text)
#part3 「ないし」処理
meisai3=[]
pattern = r"請求項(\d+)ないし(\d+)"
for ms_part in meisai2:
match = re.search(pattern, ms_part)
if match:
start = int(match.group(1))
end = int(match.group(2))
replacement = "または".join([f"請求項{i}" for i in range(start, end + 1)])
new_text = re.sub(pattern, replacement, ms_part)
new_text = new_text.rstrip("\n")#文末改行を削除
meisai3.append(new_text)
else:
meisai3.append(ms_part)
#part4 meisai.txt書き戻し
with open('meisai.txt', 'w', encoding='shift_jis') as f:
print("",file=f)
for elm in meisai3:
print("【"+elm.lstrip()) #elmの先頭のスペースを削除して【を付ける
with open('meisai.txt', 'a', encoding='shift_jis') as f:
print("【"+elm.lstrip(), file=f)
以下のサンプルをファイル名「meisai.txt」としてANSI形式で保存します。
サンプルデータ
【請求項1】制御ユニット。
【請求項2】請求項1に記載の制御ユニット。
【請求項3】請求項1または2に記載の制御ユニットを有する情報処理装置。
【請求項4】請求項1または2に記載の制御ユニットを有する情報処理装置。
【請求項5】請求項3または4に記載の情報処理装置。
【請求項6】請求項3ないし5のいずれかに記載の情報処理装置。
【請求項7】請求項3または4に記載の情報処理装置。
【請求項8】請求項4ないし7のいずれかに記載の情報処理装置。
【請求項9】請求項4ないし8のいずれかに記載の情報処理装置。
【請求項10】請求項3ないし9のいずれかに記載の情報処理装置。
【請求項11】請求項10に記載の情報処理装置。
【請求項12】請求項10または11に記載の情報処理装置。
【請求項13】請求項3ないし12のいずれかに記載の情報処理装置。
サンプルデータ(変換後)
【請求項1】制御ユニット。
【請求項2】請求項1に記載の制御ユニット。
【請求項3】請求項1または請求項2に記載の制御ユニットを有する情報処理装置。
【請求項4】請求項1または請求項2に記載の制御ユニットを有する情報処理装置。
【請求項5】請求項3または請求項4に記載の情報処理装置。
【請求項6】請求項3または請求項4または請求項5のいずれかに記載の情報処理装置。
【請求項7】請求項3または請求項4に記載の情報処理装置。
【請求項8】請求項4または請求項5または請求項6または請求項7のいずれかに記載の情報処理装置。
【請求項9】請求項4または請求項5または請求項6または請求項7または請求項8のいずれかに記載の情報処理装置。
【請求項10】請求項3または請求項4または請求項5または請求項6または請求項7または請求項8または請求項9のいずれかに記載の情報処理装置。
【請求項11】請求項10に記載の情報処理装置。
【請求項12】請求項10または請求項11に記載の情報処理装置。
【請求項13】請求項3または請求項4または請求項5または請求項6または請求項7または請求項8または請求項9または請求項10または請求項11または請求項12のいずれかに記載の情報処理装置。
プログラムのポイント
- (part1)
meisai.txtをリストmeisaiに取り込んで数値を全角→半角に変換しています。
また今回meisai.txt自体を書き換えてしまうことから、以下の構文で処理前にファイル名meisai_bk.txtのバックアップファイルを作るようにしました
shutil.copy("meisai.txt","meisai_bk.txt")
- (part2)
「請求項nまたはm」を「請求項nまたは請求項m」に変換します。
正規表現で「請求項nまたはm」の記載部分を抽出してre.sub構文で置き換え処理をしています。
pattern = r"請求項(\d+)または(\d+)"
replacement = r"請求項\1または請求項\2"
new_text = re.sub(pattern, replacement, ms_part)
- (part3)
「請求項nないしm」を「請求項nまたは請求項m」に変換します。
正規表現で「請求項nないしm」の記載部分を抽出してre.sub構文で置き換え処理をしています。
pattern = r"請求項(\d+)ないし(\d+)"
match = re.search(pattern, ms_part)
if match:
start = int(match.group(1))
end = int(match.group(2))
replacement = "または".join([f"請求項{i}" for i in range(start, end + 1)])
new_text = re.sub(pattern, replacement, ms_part)
以下のリスト内包表記でnとmの間の数値の生成をして文字列「請求項」とつなげて「請求項3または請求項4または請求項5または・・」を作成しています。
replacement = "または".join([f"請求項{i}" for i in range(start, end + 1)])
注意点1
明細書によっては「請求項n、m」や「請求項n乃至m」といった表記をしている場合がありますので、その場合プログラムのpart2、part3を以下のように書き換える必要があります。
#part2の20行を書き換える
pattern = r"請求項(\d+)、(\d+)"
#part3の29行を書き換える
pattern = r"請求項(\d+)乃至(\d+)"
注意点2
プログラムが【請求項】の「【」を手掛かりに処理(リストの分割)をしているので、想定しない場所に「【」が存在すると動作がおかしくなる可能性があります。
meisai = re.split("【",ms_base)#請求項ごとに分割する
【】は必ず【請求項】の書式として使用されるようお願いします。
最後に
注意点1に挙げたように明細書は様々な表現のパターンがありますので、パターンに応じたプログラムの書き換えが必要な場合もありますが、pythonは保守性が高いので、こういった書き換えを要するようなプログラムに対しても適しているのではと思います。
今回の記事がお役に立てれば幸いです。