Skip to content

Instantly share code, notes, and snippets.

@tamago324
Last active January 17, 2019 06:38
Show Gist options
  • Save tamago324/bce67f23d25757ee3b03b84e49ae5af8 to your computer and use it in GitHub Desktop.
Save tamago324/bce67f23d25757ee3b03b84e49ae5af8 to your computer and use it in GitHub Desktop.
ドット付き数値を整理整頓する
"""
$ cat file.txt
2.3 hoge
1.2.3 bbbbb
1.1.1 aaa
2.2.1 iine
4.2 dodo
4.2.3 dodo
$ python number_replace.py 3 file.txt
3.1 hoge
3.1.1 bbbbb
3.1.2 aaa
3.1.3 iine
3.2 dodo
3.2.1 dodo
"""
import sys
import re
from pathlib import Path
# 1.2.3 みたいなのにマッチする
number_get_pattern = re.compile(r"^\s*\d(?:\.\d)*\b")
# 小さくなったら、1にもどす
class NumberReplacor:
def __init__(self, basenumber):
# 1.2.3 の場合、の後ろの2つを持っている([2, 3])
self._number_list = []
self._basenumber = basenumber
def number_replace(self, line):
"""番号を整理する"""
# 1.2.3みたいなのを取得する
numdot_m = re.search(number_get_pattern, line)
if not numdot_m:
return line
result_dot_num = numdot_m.group()
# 上のマッチしているため、数値がマッチするのはわかっている
result_list = re.findall(r"\.\d", result_dot_num)
num_lst_len = len(result_list)
if len(self._number_list) < num_lst_len:
# 未開拓地域だったら追加する
self._number_list.append(1)
else:
if len(self._number_list) > num_lst_len:
# 小さくなっていたら(1階層上に行っていたら)、2つ目移行を削除する
# 3.1
# 3.2
# 3.2.1
# 3.2.2
# 3.3 <- ここで、[2, 2] を [2] にする
self._number_list = [self._number_list[0]]
idx = num_lst_len - 1
self._number_list[idx] = self._number_list[idx] + 1
# マッチした範囲の長さのドットを返す
# 1.2.3 なら、1.2.3を返す
lst = list(map(str, self._number_list[:num_lst_len]))
lst.insert(0, str(self._basenumber))
rep_str = ".".join(lst)
return re.sub(result_dot_num, rep_str, line)
def main():
if len(sys.argv) == 1:
print("python number_replacor.py {基礎の番号} {ファイルパス}")
return
num = sys.argv[1]
file_path = sys.argv[2]
# ファイルを読み込む
p = Path(file_path)
with open(p, "r", encoding="utf-8") as f:
txt = f.read()
num_rep = NumberReplacor(num)
for line in txt.splitlines():
print(num_rep.number_replace(line))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment