import sys, os, re, json sys.stdout.reconfigure(encoding='utf-8') base_dir = "resources/knowledge/original/원가계산/건설공사_표준품셈" all_md_files = [] for root, dirs, files in os.walk(base_dir): for f in files: if f.endswith('.md') and not f.startswith('_') and '개정사항' not in f and '2026년_건설공사_표준품셈.md' not in f: all_md_files.append(os.path.join(root, f)) total_candidates = [] # Section pattern: digit-digit(-digit)? followed by Korean letters (section title) # We want to detect when it is NOT preceded by newline/start of line # e.g. "한다.1-2-2 단위표준" or "계산한다.1-2-3 토질" sec_regex = re.compile(r'([^\n#\-\*\|\s])(\d+-\d+(?:-\d+)?\s+[가-힣\w\(\)·\,\s]+?(?:\(\'\d+[^)]*년\s*(?:보완|제정|신설)[^)]*\)|(?=\n|\([일|㎥|㎡|m|인|개|km|ton|hr|대|본|개소|소|개련|조|ha|회]))?)') for fpath in sorted(all_md_files): rel_path = os.path.relpath(fpath, base_dir) with open(fpath, 'r', encoding='utf-8') as f: text = f.read() lines = text.split('\n') file_matches = [] for line_idx, line in enumerate(lines): line_num = line_idx + 1 # find patterns in line # check if line contains a section header that didn't start at beginning # skip markdown table rows (| ... |) if line.strip().startswith('|') and line.strip().endswith('|'): continue # Regex to find attached headers # Look for e.g. text followed immediately by \d+-\d+ for m in re.finditer(r'([^\s#\-\*\>\|])(\d+-\d+(?:-\d+)?)\s+([가-힣][가-힣\s\w\(\)\/·]+)', line): prev_char = m.group(1) sec_num = m.group(2) sec_title = m.group(3).strip() # Filter out citations: e.g. '[공통부문] 5-3-1' or '‘5-3-1' if prev_char in ["'", '"', '‘', '’', '[', '(', '제', '표', '·', ':', '―', '-', '/']: continue if '참고' in sec_title[:10] or '따른다' in sec_title[:10]: continue file_matches.append({ "file": rel_path, "line": line_num, "prev_char": prev_char, "sec_num": sec_num, "sec_title": sec_title[:30], "full_match": m.group(0)[:60], "line_snippet": line[:120] }) if file_matches: print(f"{rel_path}: {len(file_matches)} candidates") total_candidates.extend(file_matches) print(f"\nTotal attached section header candidates across all 45 files: {len(total_candidates)}") with open('scratch/all_attached_headers_candidates.json', 'w', encoding='utf-8') as f: json.dump(total_candidates, f, ensure_ascii=False, indent=2)