126 lines
5.2 KiB
Python
126 lines
5.2 KiB
Python
import os, sys, re
|
|
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
|
|
base_dir = "resources/knowledge/original/원가계산/건설공사_표준품셈/02_토목부문"
|
|
|
|
job_words = [
|
|
"포장공", "보통인부", "특별인부", "철근공", "보링공", "기계설비공", "철공", "조경공",
|
|
"착암공", "용접공", "배관공(수도)", "배관공", "할석공", "석공", "줄눈공", "미장공", "도장공", "방수공",
|
|
"타일공", "내장공", "석면해체공", "궤도공", "중급기술자", "초급기술자", "고급기술자",
|
|
"형틀목공", "목도", "잠수부", "비계공", "조적공"
|
|
]
|
|
|
|
all_md_files = [os.path.join(base_dir, f) for f in os.listdir(base_dir) if f.endswith('.md')]
|
|
|
|
total_fixed = 0
|
|
|
|
for fpath in sorted(all_md_files):
|
|
fname = os.path.basename(fpath)
|
|
# Exclude 제9장_측량.md for separate specialized handling
|
|
if "제9장" in fname:
|
|
continue
|
|
|
|
with open(fpath, 'r', encoding='utf-8') as f:
|
|
lines = f.readlines()
|
|
|
|
new_lines = []
|
|
file_fixes = 0
|
|
|
|
for idx, line in enumerate(lines):
|
|
line_str = line.strip()
|
|
if not (line_str.startswith('|') and line_str.endswith('|')):
|
|
new_lines.append(line)
|
|
continue
|
|
|
|
cells = [c.strip() for c in line_str.split('|')[1:-1]]
|
|
|
|
# Skip divider or note
|
|
if all(re.match(r'^:?-+:?$', c) for c in cells if c) or (cells and cells[0] in ["비고", "비 고", "주", "[주]"]):
|
|
new_lines.append(line)
|
|
continue
|
|
|
|
# Find which cell has multiple job titles
|
|
job_cell_idx = -1
|
|
detected_jobs = []
|
|
for c_idx, c in enumerate(cells):
|
|
toks = c.split()
|
|
if len(toks) >= 2 and all(any(tok.endswith(end) for end in ["공", "부", "사", "자"]) for tok in toks):
|
|
job_cell_idx = c_idx
|
|
detected_jobs = toks
|
|
break
|
|
|
|
c_nospace = c.replace(" ", "")
|
|
cur_str = c_nospace
|
|
matched_jobs = []
|
|
for jw in sorted(job_words, key=len, reverse=True):
|
|
while jw in cur_str:
|
|
matched_jobs.append(jw)
|
|
cur_str = cur_str.replace(jw, "", 1)
|
|
if len(matched_jobs) >= 2 and cur_str == "":
|
|
ordered_jobs = []
|
|
pos = 0
|
|
while pos < len(c_nospace):
|
|
found = False
|
|
for jw in sorted(job_words, key=len, reverse=True):
|
|
if c_nospace[pos:].startswith(jw):
|
|
ordered_jobs.append(jw)
|
|
pos += len(jw)
|
|
found = True
|
|
break
|
|
if not found:
|
|
break
|
|
if len(ordered_jobs) >= 2:
|
|
job_cell_idx = c_idx
|
|
detected_jobs = ordered_jobs
|
|
break
|
|
|
|
if job_cell_idx != -1 and len(detected_jobs) >= 2:
|
|
N = len(detected_jobs)
|
|
unit_cell_idx = -1
|
|
for c_idx in range(job_cell_idx + 1, len(cells)):
|
|
toks = cells[c_idx].split()
|
|
if len(toks) == N and all(t in ["인", "대", "hr", "시간", "식", "-", "조"] for t in toks):
|
|
unit_cell_idx = c_idx
|
|
break
|
|
|
|
if unit_cell_idx != -1:
|
|
can_split = False
|
|
col_splits = {}
|
|
for c_idx in range(unit_cell_idx + 1, len(cells)):
|
|
toks = cells[c_idx].split()
|
|
if len(toks) == N and all(re.match(r'^-?\d+(?:,\d+)?(?:\.\d+)?$', t) for t in toks):
|
|
col_splits[c_idx] = toks
|
|
can_split = True
|
|
|
|
if can_split:
|
|
unit_toks = cells[unit_cell_idx].split()
|
|
for r_idx in range(N):
|
|
new_row_cells = []
|
|
for c_idx in range(len(cells)):
|
|
if c_idx == job_cell_idx:
|
|
new_row_cells.append(detected_jobs[r_idx])
|
|
elif c_idx == unit_cell_idx:
|
|
new_row_cells.append(unit_toks[r_idx])
|
|
elif c_idx in col_splits:
|
|
new_row_cells.append(col_splits[c_idx][r_idx])
|
|
else:
|
|
if r_idx == 0:
|
|
new_row_cells.append(cells[c_idx])
|
|
else:
|
|
new_row_cells.append("")
|
|
new_line_str = "| " + " | ".join(new_row_cells) + " |\n"
|
|
new_lines.append(new_line_str)
|
|
file_fixes += 1
|
|
total_fixed += 1
|
|
continue
|
|
|
|
new_lines.append(line)
|
|
|
|
if file_fixes > 0:
|
|
print(f"{fname}: fixed {file_fixes} multi-worker squashed rows")
|
|
with open(fpath, 'w', encoding='utf-8') as f:
|
|
f.writelines(new_lines)
|
|
|
|
print(f"Total multi-worker rows fixed in 토목부문 (excluding 9장): {total_fixed}")
|