Files
Aislo/resources/master_data/scripts/build_자재품목_분류.py
T
eomsangdonandClaude Sonnet 5 73109fe0e8 feat(M01): PLAN 7-4b 앞 절반 — 품셈재료 값 없는 재료 자재품목 새 줄 106 · 모래·자갈 전국지역 분리 · VR관 1본=2.5m
품셈재료 가운데 자재품목에 짝 없어 로직이 부르는 재료 106종(원 분류의 139줄 대응)을
자재품목에 새 줄로 만듦 — 이름·규격·단위·구분·상세구분·출처(품셈재료 키·요구절)만
채우고 값 다섯 칸(물가자료·유통물가·물가정보·거래가격·관급)은 모두 빔 · 비고에
「품셈재료에서 옮김 · 값 미확보」 · 키는 MT030600부터(_키대장.json 갱신).

이름이 옛 분류 규칙에 안 걸리는 93종(건설품셈 13장 플랜트설비 소모품 위주)은
build_자재품목_분류.py 에 정확한-이름 대응표를 새로 두어 채움(정규식 우선순위는
안 건드림 · 기존 30592줄 분류 결과 그대로 · 미분류 25줄 불변).

모래·자갈(중량 kg, 자재품목엔 ㎥ 지역줄만 있음)은 한 줄로 안 굳히고 전국 대표 자리 ·
지역별 자리 두 줄씩(4줄) 나눠 둠. 전력은 재료_유가전력.json 에 이미 있어 그대로 둠(안 옮김).

VR관(GF000173 막힘 원인)은 고려콘크리트산업 규격표로 1본=2.5m(D300~D1200 공통) 확인 —
그 22줄 비고에 환산 계수·출처 적음(D1500 은 표에 없어 그대로 둠).

품셈재료 자체는 이번엔 안 옮김(다음 일감) · 로직·조합 파일은 안 건드림.

typecheck 통과 · test_자재품목_분류.py·test_masterdata_check.py 80 통과(미분류 0 신규).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
2026-09-22 12:39:33 +09:00

689 lines
38 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""재료_자재품목.json 의 구분 · 상세구분 두 칸 채움 — 품명 글자 규칙(위에서 아래로 첫 일치) · 다시 돌리면 같은 결과.
· 조달청 줄(출처 「자재품목 조달청 …」) = 조달청 품명 표(조달청_분류) 를 따름
· 못 가린 줄 = 구분 「미분류」 · 상세구분 null
· 값 · 이름 · 키는 건드리지 않음 (줄 텍스트의 두 칸만 바꿈 · 나머지 글자 그대로)
· 같이 씀: ref/_묶음_자재품목.md (구분별 상세구분 · 줄 수) 를 새로 씀
사용: python scripts/build_자재품목_분류.py (JSON · 묶음 md 갱신)
python scripts/build_자재품목_분류.py --미분류 (못 가린 품명 앞쪽 나열)
"""
import collections
import json
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / "재료_자재품목.json"
OUT_MD = ROOT / "ref" / "_묶음_자재품목.md"
# 조달청 품명 → (구분, 상세구분)
조달청_분류 = {
"조경용수목": ("식생·종자", "수목"),
"수목보호용지지대": ("식생·종자", "수목지주·보호"),
"부숙유기질비료": ("식생·종자", "비료"),
"일반용폴리에틸렌관": ("관·이음관", "PE관"),
"수도용폴리에틸렌관": ("관·이음관", "PE관"),
"도로안전표지판지주": ("안전시설", "표지판·지주"),
"철제가드레일": ("안전시설", "가드레일"),
"낙석방지책": ("안전시설", "낙석방지책"),
"금속돌망태": ("매트·토목섬유", "돌망태"),
"식생매트": ("매트·토목섬유", "식생매트"),
"잔디보호매트": ("매트·토목섬유", "잔디보호매트"),
"토목용부직포": ("매트·토목섬유", "부직포"),
"자연석경계석": ("석재", "경계석"),
"투수골재포장재": ("아스콘·포장", "투수포장재"),
"목재덱": ("목재", "목재덱"),
"목재판재": ("목재", "판재"),
}
# (구분, 상세구분, 정규식) — 이름에서 공백을 모두 뺀 글자에 대고 위에서부터 첫 일치 · 좁은 규칙이 위
R = [
# 지반조사 도구
("기계·설비", "기계류", r"드라이브파이프|코아리프터|샘플러|신월튜브|코아바렐|리밍쉘"),
# 운송 · 시험 · 폐기물
("운송·용역", "화물운임", r"구역화물|폐기물운반|항만하역|운반비|운송비"),
("운송·용역", "폐기물", r"폐기물처리"),
("운송·용역", "시험·검사", r"시험(?!기|편)|출장비"),
(
"기계·설비",
"측정·시험기기",
r"시험기|시험편|탐상|측정기|계측기|측량기|판독기|분석기|필림|세륜기|축중기|레벨기|트랜싯",
),
# 레미콘 · 아스콘
("레미콘", "레미콘", r"레미콘|레디믹스"),
("아스콘·포장", "아스콘", r"아스콘|순환아스"),
("도료·방수·접착", "방수·실링", r"아스팔트(조인트|실란트|프라이머|루핑|펠트|콤파운드|방수)"),
("아스콘·포장", "아스팔트", r"^(블론|개질유화|유화)?아스팔트(유제)?$|록크하드"),
(
"아스콘·포장",
"포장블록",
r"잔디블록|바닥벽돌|투수콘|투수블[록럭]|고압블록|규사블록|다색(저속|블록)|점자블록|인터로킹|보도블[록럭]|차도블록",
),
# 밸브 · 수도 (수도미터 는 스트레이너보다 먼저)
("밸브·수도자재", "수도계량기·유량계", r"수도미터"),
(
"밸브·수도자재",
"밸브",
r"밸브|제수|체크|게이트|감압|스트레이너|수전|분수전|공기변|수문|콕크",
),
("밸브·수도자재", "수도계량기·유량계", r"수도미터|계량기|유량계|미터기|보호통"),
("밸브·수도자재", "스프링클러·호스", r"스프링클러|살수|급수호스|송수호스|호스|분사|헤드|점적"),
("밸브·수도자재", "펌프", r"펌프|양수기"),
("도료·방수·접착", "방수·실링", r"백업재"),
("관·이음관", "단열이중관", r"단열이중"),
("기계·설비", "보일러·공조", r"정화조"),
# 거푸집 (문양거푸집 등 — 단열 글자보다 먼저)
(
"거푸집·가설재",
"거푸집",
r"거푸집|유로폼|알폼|코팅합판|폼타이|플랫타이|분리제|박리제|폼핀|핀폴|패널(?!스위치)|내부코너",
),
# 단열 · 보온
(
"단열·보온",
"단열재",
r"단열(?!문)|보온|샌드위치|폴리스티렌|스티로폼|암면|글라스울|압출법|페놀폼|은박지",
),
# 동바리·비계 (철물·브라켓 글자보다 먼저)
(
"거푸집·가설재",
"동바리·비계",
r"동바리|비계|낙하물|가설|가시설|버팀|흙막이|스트럿|안전발판|건설발판|발판|사다리|가림막|가세틀|바퀴\(|조립식틀|시스템동바리|스카폴드",
),
# 볼트 · 앵커 · 철물 중 관·형강과 겹치는 것을 먼저
("볼트·앵커·철물", "철근커플러", r"철근커플러|커플러|정착구"),
("볼트·앵커·철물", "앵커", r"앵커|앙카|케미칼|카트리지|인서트"),
(
"볼트·앵커·철물",
"볼트·너트",
r"볼트|볼트너트|못트|너트|와셔|스크류|스크루|리벳|스터드|턴버클|고정핀|앵커핀|나사(?!식)|철나사|직결",
),
("볼트·앵커·철물", "못", r"철못|타정|콘크리트못|STS못|벨가못|꺾쇠|표시못"),
(
"볼트·앵커·철물",
"와이어로프·클램프",
r"와이어로프|P\.P로프|클램프|훅클램프|행거|철물|지지금구|연결금구|브라켓|샤클|피뢰침",
),
("전기·통신", "전선관·트레이", r"전선관"),
# 도료 · 방수 · 접착 (좁은 것)
(
"도료·방수·접착",
"방수·실링",
r"방수|실런트|실란트|실링|코킹|지수재|씰$|백업재|충진|퍼티|벤토나이트(?!매트)|방식테이프|줄눈재|물끊기",
),
(
"도료·방수·접착",
"도료",
r"페인트(?!붓)|프라이머|신너|시너|희석제|도료|코팅제|래커|에나멜|방청|광명단|징크|안료|염료|표면처리제|표면강화제|피막양생|양생제|나노큐브|하도|상도",
),
(
"도료·방수·접착",
"접착·혼화",
r"접착|본드|(?<!합성)수지(?!\))|레진|혼화|감수제|AE제|지연제|경화제|바인더|라텍스|폴리탑|메도킹|고무패킹|패킹|가스켓",
),
# 식생 · 종자
("식생·종자", "종자", r"종자|산림종묘|배합종자"),
(
"식생·종자",
"비료·토양개량",
r"비료|생육|영양제|침식안정제|토양개량|피트모스|펄라이트|유기질|인공토양|상토|배양토|퇴비",
),
("식생·종자", "농약·약제", r"살충제|살균제|제초제|농약|훈증약제|방제약|기피제"),
(
"식생·종자",
"수목지주·보호",
r"수목지주|지주대|수목보호|수간주입|수목표찰|수목영양|나무보호|수목받침|수목고정",
),
(
"식생·종자",
"잔디·지피",
r"잔디|줄떼|평떼|지피|초화|비비추|맥문동|원추리|꽃양귀비|수레국화|패랭이|국화|억새|갈대|송엽국|들꽃|야생화|구근",
),
(
"식생·종자",
"수목",
r"나무(\(|,|$)|나무$|소나무|곰솔|해송|주목|금송|낙우송|메타세쿼이아|측백|향나무|철쭉|산홍|산수유|목련|단풍|벚|동백|무궁화|회양목|배롱|은행|느티|팽나무|회화|서어|물푸레|이팝|층층|칠엽수|계수|산딸|먼나무|모과|감나무|대추|마가목|복자기|산사|살구|사철|쥐똥|꽝꽝|남천|피라칸|조팝|개나리|장미|수국|라일락|수수꽃다리|박태기|낙상홍|화살|병꽃|불두화|히어리|야광|다정큼|당종려|종려|소철|대나무|조릿대|등나무|능소화|담쟁이|송악|마삭|인동|덩굴|아이비|칠자화|왕버들|수양|능수|진달래|백송|과꽃|옥매화|꽃양배추|화백|버들|유카|율마|허브|채송|봉선|일일초|안개초|꽃무릇|영춘화|양매자|식물재배화단|철쭉류|사스레|황매|명자|백량금|협죽도|만리화|말발도리|골담초|아로니아|오죽|올괴불|황근|풍년화|태산목|용버들|옥향|담팔수|무화과|나한송|구상나무|편백|눈향|눈주목|비자|가시|후박|녹나무|후피향|아왜|굴거리|팔손이|목서|치자|서향|광나무|보리수|버드|갯버들|포플러|사시|아까시|싸리|자귀|주엽|쉬나무|개오동|때죽|쪽동백|고로쇠|당단풍|산벚|왕벚|겹벚|자엽|해당화|꽃사과|꽃복숭|모감주|황칠|노각|밤|호두|가래|음나무|두릅|오동|참죽|옻|붉나무|말채|백당|덜꿩|병아리|고욤|헛개|꾸지|뽕|닥|미루|사과|배$|돌배|앵두|자두|석류|유자|귤|감귤|매실|살구|블루엔젤|에메랄드|쏠라데리|사피니아|라벤다|아스타|제라늄|버베나|빈카|범부채|아게라|익소라|에키네시아|카네이션|실유카|채진목|숙근|웨이브페츄니아|나리|매미꽃|금낭화|땅채송화|사초|붓꽃|할미꽃|돌나물|돌장미|초롱|프리뮬라|팬지|비올라|페튜니아|메리골드|샐비어|맨드라미|코스모스|해바라기|수선|튤립|히아신스|크로커스|백합|창포|부들|연꽃|수련|물칸나|칸나|달리아|글라디올러스|아이리스|맥문|옥잠|가는잎|수크령|갈풀|띠|톱풀|꿩의비름|세덤|기린초|돌단풍|둥굴레|은방울|모란|작약|우산|양지꽃|뚝갈|벌개미취|구절초|쑥부쟁이|층꽃|꽃댕강|댕강|황금|미선|서부|미국|서양|중국|무늬|은사초|그린톱|그라스|핑크뮬리|팜파스|수생|정수식물",
),
("식생·종자", "수목", r"^H\d{1,2}(\.\d+)?[×xX*,]\s*[RBWrbw]\d"),
# 시멘트 · 골재
(
"시멘트·골재",
"시멘트",
r"^(백|초속경|초조강|무수축|포틀랜드)?시멘트(?!벽돌|블록|라이닝|몰탈|모르타르|판|기와)",
),
("시멘트·골재", "모르타르", r"모르타르|몰탈|그라우트|무수축"),
(
"시멘트·골재",
"골재",
r"골재|쇄석|^모래|석분|자갈|잡석|부순돌|마사토|호박돌|성토재|사질토|규사",
),
# 안전시설 (관·형강보다 먼저 — 휀스 · 지주)
("안전시설", "가드레일", r"가드레일|방호울타리|방호책|충격흡수|완충시설|방호벽"),
(
"안전시설",
"표지판·지주",
r"표지판|표지병|안전표지|도로표지|안내판|표찰|반사경|반사지|시선유도|경계표주|알림표지|지주(?!대)",
),
(
"안전시설",
"낙석방지·휀스",
r"칼라각관|낙석방지|방책|방음|볼라드|휀스|펜스|난간|라바콘|안전화|안전모|안전대|안전망|추락방지|방지턱|안전띠|바리케이",
),
# 거푸집 · 가설재
# 목재
("목재", "합판", r"합판|MDF|OSB|파티클|섬유판|텍스|석고보드"),
(
"목재",
"각재·판재",
r"각재|판재|미송|외송|방부|원목|목재|우드칩|통나무|낙엽송|구조목|멀바우|데크(?!플레이트|패널|고정)|삼나무|편백(?!나무)|경계목|면목|침목",
),
# 매트 · 토목섬유
("매트·토목섬유", "돌망태·사방", r"돌망태|개비온|망태석|사석|녹생토|녹화|사방|이불형"),
(
"매트·토목섬유",
"부직포·토목섬유",
r"부직포|지오텍스|지오그리드|지오콤|지오셀|토목섬유|차수시트|드레인보드|배수판|투수시트|섬유지|네트|오탁방지|보호망|그물",
),
("매트·토목섬유", "매트", r"매트|멀칭|코이어|방초|고화매트|벤토나이트매트"),
# 석재
("석재", "경계석", r"경계석|도로경계|측석"),
(
"석재",
"조경석·자연석",
r"조경석|자연석|호박석|^산석|경관석|판석|사고석|야면석|막돌|다듬돌|석재|화강석|대리석|현무암|사암|점판암",
),
# 콘크리트제품
(
"콘크리트제품",
"말뚝·파일",
r"콘크리트말뚝|PC말뚝|PHC|콘크리트파일|복합말뚝|강관파일|강관말뚝|쉬트파일|시트파일|강널말뚝|팽이파일|측량말뚝|전기저항용접강관파일",
),
("콘크리트제품", "PC구조물", r"조립식PC|프리캐스트|PC맨홀|PC박스|PC개량|PC우수"),
(
"콘크리트제품",
"경계석·블록",
r"콘크리트경계|보차도경계|경계블록|시멘트벽돌|시멘트블록|보강토|GS|옹벽블록|호안블록|생태호안|식생호안|블록|벽돌",
),
# 맨홀 · 수로 · 그레이팅
("맨홀·수로·그레이팅", "그레이팅", r"그레이팅|트[렌랜]치|격자"),
(
"맨홀·수로·그레이팅",
"맨홀",
r"뚜껑|맨홀|인상링|우수받이|집수정|측구뚜껑|주철뚜껑|집수구|물받이(?!후)|침투측구|받이",
),
(
"맨홀·수로·그레이팅",
"수로관",
r"수로|플륨|암거|개거|배수로|측구|벤치플|[UL]형(측구|수로|플륨|배수)",
),
# 관 — 재질별
("잡재료", "소모품", r"PVC(용접봉|코팅|시트|바닥|선|천막)"),
("관·이음관", "흄관", r"흄"),
("관·이음관", "파형강관", r"파형강관|파형관|커플링밴드|수밀벨트"),
(
"관·이음관",
"PVC관",
r"(?<![A-Za-z])(PVC|P\.V\.C|VR|VG|XL|PB|CPVC|PRC)|내충격|염화비닐|고강성|레진관",
),
(
"관·이음관",
"PE관",
r"^PE|폴리에틸렌|HDPE|(?<![A-Za-z])PE|HI-?(PER|GP|3R|3P|VP)|이중벽|다중벽|삼중벽|유공관|하수관|우수관|융착",
),
(
"관·이음관",
"주철관",
r"주철|(?<![A-Za-z])(KP|PM|HP)|덕타일|닥타일|타이튼|메카니칼|압륜|이탈방지|접합부속",
),
(
"관·이음관",
"유리섬유·FRP관",
r"FRP(파이프|덕트|관|이음|곡관)|GFRP(관|파이프)|유리섬유(곡관|복합관|관|파이프|덕트)|섬유복합관",
),
("관·이음관", "동관·스텐관", r"동관|스텐관|스테인리스관|STS관|SUS관|STS(파이프|배관)"),
(
"관·이음관",
"강관",
r"강관|배관용|압력배관|흑관|백관|가스관|피복강관|도복장|에폭시강관|쉬즈관|비굴착|관세척|나팔관|스틸파이프|STEELPIPE|파이프",
),
(
"관·이음관",
"이음쇠·부속",
r"STS(티|캡|엘보|레듀)|이경|티이|엘보|니플|레듀[샤셔]|유니온|소켓|플랜지|곡관|편락|엔드캡|엔드플러그|이형관|이음쇠|이음관|분기관|새들|플럭|마개|선단캡|노말밴드|˚밴드|연결구|주름관|플렉시블|플렉스",
),
# 철근 · 강재 (추진관 은 철근보다 먼저)
("관·이음관", "흄관", r"추진관"),
("철근·강재", "철근", r"철근"),
("철근·강재", "철망·와이어메쉬", r"와이어메[쉬시]|용접철망|^철망|크림프철망|메쉬"),
("철근·강재", "철선", r"철선|결속선|어닐링|아연도철|PC강선|강선"),
(
"철근·강재",
"형강",
r"[Hh]형강|[ㄱㄷ]형강|^[ICT]형강|C형강|^(STS)?앵글$|평강|평철|각철|4각강|환봉|봉강|철평석|강봉|H빔|[Hh]-?빔",
),
(
"철근·강재",
"강판",
r"(?<!보)강판|후판|동판|열연|냉연|철판|스틸플레이트|데크플레이트|기초플레이트|복공판|탄소주강",
),
("철근·강재", "구조용강관", r"구조용|각관|반경철관|철관"),
# 전기 · 통신
("전기·통신", "케이블·전선", r"케이블|CABLE|^전선|전선$|HFIX|HIV|접지|절연|배선(?!용)"),
("전기·통신", "전선관·트레이", r"전선관|TRAY|트레이|풀박스|분전함|박스"),
(
"전기·통신",
"판넬·차단기",
r"차단기|접촉기|릴레이|분전반|제어기|제어반|스위치|콘센트|PLC|타이머|인버터|변압기|SK판넬|TS판넬|퓨즈|전원용",
),
(
"전기·통신",
"조명·전등",
r"LED|조명|램프|등기구|투광|보안등|안정기|경광등|경고등|유도등|신호등|가로등|등주",
),
# 기계 · 설비
(
"기계·설비",
"보일러·공조",
r"보일러|공조|에어컨|환풍|송풍|히터|화장로|버너|탱크|물탱크|저류조|열교환|팬틸트|정화조",
),
(
"잡재료",
"용접·가스",
r"프로판가스|탄산가스|프레온가스|아세틸렌|^(용접|산소|알곤|아르곤)|용접봉",
),
("기계·설비", "소방·가스", r"소방|소화(?!화)|소화전|가스믹서|가스버너|경보|감지기|방화"),
(
"기계·설비",
"기계류",
r"유압잭|잭써포트|모터|전동기|기어|감속기|베어링|해머|브레이커|톱|드릴|비트|블레이드|코아|롤러|다짐|믹서|용접기|절단기|발전기|콤프레샤|컴프레샤|비트|리밍쉘|스텝|공구",
),
(
"기계·설비",
"놀이·운동·시설물",
r"놀이|운동기구|의자|벤치|파고라|퍼걸라|쓰레기통|분리수거함|음수대|조형물|정자",
),
# 건축마감
("건축마감", "타일·기와", r"타일|테라조|기와|세라믹|도기"),
(
"건축마감",
"문·창·유리",
r"도어|(?<![가-힣])문|문(?=\(|,|$)|문틀|문비|창호|(?<!섬)유리|샤시|경첩|손잡이|자물쇠|힌지|셔터|블라인드",
),
(
"건축마감",
"천장·바닥·마감재",
r"천장|천정|흡음|석고|후레싱|후레임|칸막이|바닥재|카페트|마감|몰딩|걸레받이|조이너|루버|점검구|코너비드|논슬립|계단",
),
("건축마감", "위생기구", r"대변기|세면기|소변기|양변기|욕조|싱크"),
# 교량 · 구조 부속 · 특수포장 · 기타 좁은 규칙
(
"교량·구조부속",
"신축이음·받침",
r"신축이음|교량받침|익스펜션조인트|익스팬션조인트|EJ|내진탄성받침|교량배수|받침",
),
(
"교량·구조부속",
"보강재·정착",
r"PC강연선|GFRP보강근|DB정착바|강섬유|다웰바|스페이셔|SOC-?BAR|간격재|장선연결|콘크리트근가|SRR보강재",
),
("아스콘·포장", "특수포장", r"소일콘포장|탄성포장|황토포장|미끄럼방지포장|탑쏘일|포장재"),
("거푸집·가설재", "가설건축물", r"콘테이너|컨테이너"),
("매트·토목섬유", "부직포·토목섬유", r"그리드|구갑망|메탈라스|스텐리스망|식생토낭"),
(
"전기·통신",
"부속·기타",
r"슬리브|부스바|애자|수평도체|터미날|CONNECTOR|백열|형광등|보조등|철주|콘크리트주|보행등|접속관",
),
(
"안전시설",
"차선·방호",
r"차선규제|계선주|단부레일|라운드레일|DS연결대|DS차광망|핸드레일촉지판",
),
(
"관·이음관",
"이음쇠·부속",
r"부싱|STS직관|안장티|THP|(?<![A-Za-z])STS(플러그|캡)|SUS밴드|연결관|알루미늄관|후렉시블|유공도수관|다발관|조립식배수구|에어밴트|수도꼭지",
),
("볼트·앵커·철물", "와이어로프·클램프", r"로프|가마니|클립|타카핀|착지핀|칼블럭"),
(
"도료·방수·접착",
"도료",
r"락카|왁스|바탕조정제|주입용에폭시|주입재|씰링재|구체강화제|타르페이퍼|봉함재",
),
("잡재료", "화약", r"폭약|뇌관"),
("잡재료", "용수", r"^물\(상수도"),
("잡재료", "고철·기타금속", r"고철|봉땜납"),
("잡재료", "용접·가스", r"아세톤"),
("철근·강재", "형강", r"트러스|중도리"),
("건축마감", "천장·바닥·마감재", r"T-?BAR"),
("거푸집·가설재", "동바리·비계", r"수평재|수직재"),
("도료·방수·접착", "접착·혼화", r"기포제"),
("잡재료", "소모품", r"^풀\(|보양지|소창"),
# 잡재료
("잡재료", "용접·가스", r"팁\(날\)|알곤용접봉"),
(
"잡재료",
"소모품",
r"장갑|걸레|비닐|페인트붓|^붓$|사포|브러[시쉬]|톱날|연마|숫돌|기름|오일|윤활|그리스|목탄|비누|현수막|끈|밧줄|포대|마대|볏짚|양생포|필름|테이프|와이어",
),
# 보강 — 미분류 꼬리 (기존 규칙 뒤에 붙임 · 앞 규칙 결과는 그대로)
(
"식생·종자",
"수목",
r"^(가우라|가랑코에|덴드롱|디기탈리스|루피너스|리아트리스|만데빌라|밀렛|블루세이지|비덴스|산파첸스|스토크|시클라멘|아로우카리아|아르메리아|안젤로니아|알리움|애니시다|임파첸스|이포메아|쥬리안|캄파놀라|크로톤|클레오메|토레니아|펜타스|포인세티아|한련화|장비와인핑크|꿀풀|좁쌀풀|향토초본류|향토목본류|초본류)$",
),
(
"식생·종자",
"농약·약제",
r"발근촉진제|수목도포제|전착제|카바액제|푸른솔|에코마인|증산억제제|황산동|질산칼[륨슘]|제1인산칼륨|요소|용과린|입단형성제|토양보습제|생명분|대지생명",
),
(
"식생·종자",
"수목",
r"녹매토|GP토|부엽토|배합토|인공토|복합토|에코토|생태복원토양|바크|세라소일|부엽식물|론생백|씨앗부착거적|피복재|법면안정재|천연섬유망",
),
("식생·종자", "수목", r"화분|그린폴|그린엣지|드립엣지|가로수보호판"),
("시멘트·골재", "시멘트", r"시멘트|슬래그|코우크스|SMT기층용결합재|프롬"),
(
"시멘트·골재",
"모르타르",
r"줄눈(샌드|채움)|PFM|고경도줄눈|알[칼카]리(성)?회복제|침투형알칼리|중성화|탄산화|염해|탄성보수재|방오코팅|RA-|MA(코트|콘|프라이몰)|폴리(코트|콘)|Recoh|균열(방지|저감)|바탕조정재|급결제|표면보호용|하이브리드섬유보강|나선형보강재|타스|워터스탑|몰[트더]|본크론|코타스|믹스|하이루|아루텍|에스몰|새지마|메토셀|비안새|뉴스타|탑스톤|HiCon|HI-PAT|VES|E-005S|JSM|고능축완결재|광촉매에폭시|에멀젼|파우더|필러|F-Tape|CERACOTE|포시몰|KL-화인|바니쉬|S\.R",
),
(
"도료·방수·접착",
"접착·혼화",
r"규산소다|염화칼슘|생석회|소석회|친환경수용성녹제거제|착색제|GRPS활성제",
),
(
"잡재료",
"소모품",
r"유압유|절삭유|LPG|무연분탄|복사용지|인쇄잉크|모조지|영상인화지|저장매체|USB메모리|건전지|배터리|축전지|에칠알콜|밀가루|요소수|카바이트|질소|탄산칼슘|산$|염산|인산|수산|알루미늄분말|알루미늄괴|넝마|새끼|빗자루|FILMCASSETTE|COUPLANT|형광자분|자분|침투통|비산먼지방지망|분진망|차광망|손전등",
),
(
"잡재료",
"고철·기타금속",
r"주물|동합금선|황동선|골함석|압착그립|연결체인|파일용접밴드|암타이밴드|천연밴드|나일론밴드|후크|지압판|웨지핀|케이지",
),
("잡재료", "화약", r"도폭선|미진동파쇄제|발파전석"),
("석재", "경계석", r"전석|해미석|인조석|게비온석|디딤석"),
("콘크리트제품", "PC구조물", r"비탈면보호블럭|블럭조임재|생태목틀|SSM|무소음트랜치|고무블럭"),
(
"안전시설",
"가드레일",
r"표지|칼라콘|슈퍼콘|제설함|윙카등|디자인형울타리|울타리|핸드레일|방충재|방현|외장재\(교량|휴먼보강캡",
),
(
"매트·토목섬유",
"부직포·토목섬유",
r"Geogrid|지오드레인|직포|BSA시트|프로텍션|펠트|RS강화|SRR고정구|부착망|고무판|고무바|라인벨트|완충고무",
),
(
"건축마감",
"천장·바닥·마감재",
r"판넬|PANEL|캐노피|CANOPY|ROOFSHEET|지붕판|슁글|합지벽지|폴리카보네이트|아크릴|포멕스|썬라이트|FRP|알루미늄(판|캡)|STS(헤어라인|원형봉)|강재판넬|T챤넬|엘브엣지|베이스(커버|찬넬)|보호금구|상부캡|워셔캡|주주|SS높이조절|QMR|K-SPAN|L형고정|스프라이스|보호캡|연결핀|JACK-BOLT|완충브래킷|Plate|PPP|평상|테이블|책상|야외|분리수거장|축대목|외부|내부|미끄럼방지",
),
(
"전기·통신",
"제어·계측기기",
r"콘덴서|UPS|MONITOR|TOUCHPANEL|LSUBoard|하이넬|USB|운전화면|DB$|자동탈착|MT자외선|ECTPROBE|FIELDINDICATOR|SURVEYMETER|MAGNETICCHUCK|MAGNETIC|JISA형시편|초음파탐촉자",
),
(
"기계·설비",
"기계류",
r"치즐|백호우티스|BIT|비트|TAPER|핸들패커|코어리프터|유압할암봉|에어타카|에어튜브|모듈러잭|로내대차|배기가스|재연소로|집진장치|필터백|유해가스촉매|건조기|캐스터블|래크|DUCT|FLEXIBLE|오수처리|미생물담체|다공성여재|정화침투|공드럼|홈메우기|파일안전덮개|일반고무판|데리네이트|폴리에스터펠트|내마모",
),
(
"건축마감",
"천장·바닥·마감재",
r"벽지|한지장판지|도배지|운용지|롤스크린|큐비클|세면대|캐비넷|APRON|수건|휴지걸이|컵대|옷걸이|거울|국기꽂이|베너기|차광막|오메가레일",
),
(
"도료·방수·접착",
"접착·혼화",
r"ERH-|SLC-|SC604A|레팔트|BACKUPROD|패칭재|알카리회복재|부식방지제|함침재|씰링용에폭시|전해질저감재|탄소저감재|재생첨가제|블랙터|원타임|ㄷ-보강재|주제$",
),
(
"잡재료",
"소모품",
r"방진|보안경|리어카|바퀴|쟈키|와샤|Screw|그라인더날|건축용주사기|거울원판|가루분|^풀$|호차|취부밴드|CruzerBlade|CM01-|프린터|COMPUTER|서버용PC",
),
(
"기계·설비",
"기계류",
r"에어햄머|롯드페카|샘풀|SPT|리밍셀|패커|P\.C콘|파일캡|연결판|고정판|분수용기기|고압분무|쿨링포그|정수필터|압력게이지|송관대차|관운반차|수골|대차|냉각장치|집진기|펄스유니트|인젝트|예열기|잔재처리|배풍기|배기관|유골|백연방지|다이옥신|단열문|제어함열처리",
),
(
"전기·통신",
"제어·계측기기",
r"Board|CPU|ROM교체|MMI|감전보호기|화재주수신기|점멸기|음향신호기|위성시보기|낙뢰|TIMER|전력량계|계전기|중앙감시반|조작반|모니터장치|안내시스템|재실감지|Modem|단자함|전용회선|CONT\(SCU\)",
),
(
"전기·통신",
"케이블·전선",
r"경동|연동연선|지선롯드|경완금|FC통신관|팔각테파관강주|근가밴드|랙크|Y캡",
),
("철근·강재", "형강", r"I\"형행가|열녀목|STSSR캡"),
("관·이음관", "동관·스텐관", r"^배관$"),
("전기·통신", "전선관·트레이", r"RACEWAY|PULLBOX|ELBOW|C-찬넬"),
(
"전기·통신",
"제어·계측기기",
r"카메라|렌즈|검지|제어장치|전원장치|서브랙|단자대|제어함체|철구조물\((신호|과속)",
),
(
"시멘트·골재",
"모르타르",
r"모르터|폴리머(콘크리트|결합재)|SS섬유재|충전재|SMT표층|스틸화이바|네오스톤",
),
("기계·설비", "측정·시험기기", r"압력계|ALARMDOSIMETER|UVMETER|TEMPILSTIK|MEGA-CHECK"),
("기계·설비", "기계류", r"권양기|공기주입기|벨트\(|악취방지|UV살균기|예취기|스핀틀|공기배기구"),
("식생·종자", "수목", r"촉촉소일|나무여과상자|만병초"),
("석재", "경계석", r"빗물머금석"),
("잡재료", "소모품", r"마킹펜|크레용|세척제|WHITEPAINT|보조통|암등|이단철개|열수축시트"),
# 일감 3 — 뒤에 붙여 옛 결과는 그대로
("운송·용역", "상하차", r"^(상|하)차비$"),
("식생·종자", "초본·야생화", r"^칡$"),
("특수장비", "특수장비", r"AirHammer|콘쉴드|바탕면조정재|본우드"),
]
RX = [(a, b, re.compile(c, re.I)) for a, b, c in R]
# 화초·수생식물 줄 — 규격이 분·포트·cm·분얼·개화구·엽·년생 꼴 (이름 글자로는 못 가림)
식물규격 = re.compile(r"^\d+(\.\d+)?cm$|포트|분얼|개화구|\d엽$|년생|\d+cm분$")
# PLAN 7-4b — 품셈재료에서 자재품목으로 옮긴 새 줄(값 미확보) 이름 → (구분, 상세구분)
# 위 정규식 규칙에 안 걸리는 건설품셈 13장 플랜트설비 소모품 위주 · 이름 그대로(공백만 뺌) 견줌 · 영문은 대소문자 안 가림
품셈이관_분류 = {
"지수활제": ("도료·방수·접착", "방수·실링"),
"jointfiller": ("도료·방수·접착", "방수·실링"),
"스티로폴": ("단열·보온", "단열재"),
"tarpaper": ("도료·방수·접착", "방수·실링"),
"채움재(아스팔트)": ("도료·방수·접착", "방수·실링"),
"콘크리트표면강화재(하드너)": ("도료·방수·접착", "도료"),
"틈메우기돌": ("석재", "조경석·자연석"),
"깃발": ("안전시설", "표지판·지주"),
"피복제": ("도료·방수·접착", "도료"),
"침식방지안정제": ("식생·종자", "비료·토양개량"),
"basechannel": ("건축마감", "천장·바닥·마감재"),
"topchannel": ("건축마감", "천장·바닥·마감재"),
"축중계(이동식)": ("기계·설비", "측정·시험기기"),
"보호막": ("도료·방수·접착", "도료"),
"보조강재": ("철근·강재", "형강"),
"flux": ("잡재료", "용접·가스"),
"질석": ("단열·보온", "단열재"),
"정배지": ("건축마감", "천장·바닥·마감재"),
"알루미늄핀": ("거푸집·가설재", "거푸집"),
"표준보강메시": ("철근·강재", "철망·와이어메쉬"),
"고강도메시": ("철근·강재", "철망·와이어메쉬"),
"실리콘": ("도료·방수·접착", "방수·실링"),
"아스팔트싱글": ("건축마감", "천장·바닥·마감재"),
"노즐": ("기계·설비", "기계류"),
"nozzle": ("기계·설비", "기계류"),
"테르밋용재": ("잡재료", "용접·가스"),
"몰드": ("잡재료", "용접·가스"),
"골무": ("잡재료", "용접·가스"),
"철구(shotball)": ("잡재료", "소모품"),
"철편(grit)": ("잡재료", "소모품"),
"동력brush": ("잡재료", "소모품"),
"wirebrush": ("잡재료", "소모품"),
"컴파운드": ("잡재료", "소모품"),
"슈": ("기계·설비", "측정·시험기기"),
"베인전용로드": ("기계·설비", "측정·시험기기"),
"로드": ("기계·설비", "측정·시험기기"),
"표준사": ("기계·설비", "측정·시험기기"),
"단독콘": ("기계·설비", "측정·시험기기"),
"코크스": ("잡재료", "소모품"),
"sandpaper": ("잡재료", "소모품"),
"여과기": ("잡재료", "소모품"),
"세유": ("잡재료", "소모품"),
"grease": ("잡재료", "소모품"),
"machineoil": ("잡재료", "소모품"),
"gasoline": ("잡재료", "소모품"),
"galvanizedwire": ("철근·강재", "철선"),
"grindingwheel": ("잡재료", "소모품"),
"보일유": ("잡재료", "소모품"),
"hacksawblade": ("잡재료", "소모품"),
"drill": ("기계·설비", "기계류"),
"grinderwheel": ("잡재료", "소모품"),
"file": ("잡재료", "소모품"),
"oilstone": ("잡재료", "소모품"),
"광목": ("잡재료", "소모품"),
"붕사": ("잡재료", "용접·가스"),
"compound": ("잡재료", "소모품"),
"3-bond": ("잡재료", "소모품"),
"전기용접": ("잡재료", "용접·가스"),
"탄소봉": ("잡재료", "용접·가스"),
"grinder": ("기계·설비", "기계류"),
"돌": ("잡재료", "소모품"),
"film": ("기계·설비", "측정·시험기기"),
"탈에폭시레신": ("도료·방수·접착", "접착·혼화"),
"그라인더돌": ("잡재료", "소모품"),
"tarepoxy": ("도료·방수·접착", "도료"),
"마린b/t(선박도로용)": ("도료·방수·접착", "도료"),
"zincprimer": ("도료·방수·접착", "도료"),
"m/coil": ("잡재료", "소모품"),
"washer": ("볼트·앵커·철물", "볼트·너트"),
"sealtape": ("잡재료", "소모품"),
"백묵": ("잡재료", "소모품"),
"석필": ("잡재료", "소모품"),
"흑welderglass": ("잡재료", "소모품"),
"백welderglass": ("잡재료", "소모품"),
"오스터날": ("기계·설비", "기계류"),
"탭": ("기계·설비", "기계류"),
"다이스": ("기계·설비", "기계류"),
"정": ("잡재료", "소모품"),
"centerpunch": ("기계·설비", "기계류"),
"대강": ("잡재료", "소모품"),
"유지": ("잡재료", "소모품"),
"중유": ("잡재료", "소모품"),
}
def 분류(이름: str, 출처: str, 규격: str = ""):
n = re.sub(r"\s+", "", 이름 or "")
if 출처.startswith("자재품목 조달청"):
return 조달청_분류.get(n, ("미분류", None))
if not n:
return ("미분류", None)
for a, b, rx in RX:
if rx.search(n):
return (a, b)
if n.casefold() in 품셈이관_분류:
return 품셈이관_분류[n.casefold()]
if 규격 and 식물규격.search(규격.replace(" ", "")):
return ("식생·종자", "초본·야생화")
return ("미분류", None)
LINE = re.compile(r'("구분": )(?:null|"[^"]*")(, "상세구분": )(?:null|"[^"]*")')
NAME = re.compile(r'"이름": "((?:[^"\\]|\\.)*)"')
SRC_ = re.compile(r'"출처": "((?:[^"\\]|\\.)*)"')
NOTE_OLD = "구분 · 상세구분 = 원문에 대·중분류 칸이 없어 비움(지어내지 않음)"
NOTE_NEW = "구분 · 상세구분 = 품명 글자 규칙으로 채움(scripts/build_자재품목_분류.py · 묶음 목록 ref/_묶음_자재품목.md) · 조달청 줄은 조달청 품명을 따름 · 못 가린 줄은 「미분류」"
NOTE_EMPTY = "이름 없음 — 원문 품명 칸이 빈 줄이라 분류하지 않음"
def q(s):
return "null" if s is None else json.dumps(s, ensure_ascii=False)
def main():
text = SRC.read_text(encoding="utf-8")
rows = json.loads(text)["줄"]
out, res = [], []
for ln in text.split("\n"):
m = LINE.search(ln)
if m and '"키": "MT' in ln:
nm = json.loads('"' + NAME.search(ln).group(1) + '"')
sc = json.loads('"' + SRC_.search(ln).group(1) + '"')
sp = re.search(r'"규격": "((?:[^"\\]|\\.)*)"', ln)
a, b = 분류(nm, sc, json.loads('"' + sp.group(1) + '"') if sp else "")
ln = LINE.sub(lambda _: f'"구분": {q(a)}, "상세구분": {q(b)}', ln, count=1)
if not nm:
ln = ln.replace('"비고": null', f'"비고": "{NOTE_EMPTY}"', 1)
res.append((a, b, nm))
out.append(ln.replace(NOTE_OLD, NOTE_NEW))
assert len(res) == len(rows), (len(res), len(rows))
return "\n".join(out), res
def 묶음_md(res):
by = collections.defaultdict(collections.Counter)
for a, b, _ in res:
by[a][b or "—"] += 1
ks = sorted((k for k in by if k != "미분류"), key=lambda k: -sum(by[k].values()))
ndet = sum(len(by[k]) for k in ks)
L = [
"# 자재품목 묶음 (구분 · 상세구분)",
"",
"`scripts/build_자재품목_분류.py` 가 만든 표 — 손으로 고치지 않음.",
"",
f"- 구분 {len(ks)} · 상세구분 {ndet} · 미분류 {sum(by['미분류'].values())} 줄 (전체 {len(res)} 줄)",
"",
"## 규칙",
"",
"- 품명에서 공백을 모두 뺀 글자에 정규식을 위에서부터 대어 첫 일치를 따름 — 순서가 곧 우선순위.",
"- 조달청 줄(출처 「자재품목 조달청 …」)은 조달청 품명 16 개 표를 따름.",
"- 못 가린 줄은 구분 「미분류」 · 상세구분 없음.",
"- 값 · 이름 · 키는 바꾸지 않음(두 칸만).",
"- 다시 돌리면 같은 결과.",
"",
"## 구분별 상세구분 (줄 수)",
"",
]
for k in ks:
L.append(f"### {k} ({sum(by[k].values())})")
L.append("")
L.append(" · ".join(f"{d} {c}" for d, c in by[k].most_common()))
L.append("")
return "\n".join(L)
def apply():
"""빌더가 JSON 을 새로 쓴 뒤 부름 — 두 칸 · 머리 비고를 다시 채움."""
new, res = main()
SRC.write_text(new, encoding="utf-8", newline="\n")
OUT_MD.write_text(묶음_md(res), encoding="utf-8", newline="\n")
return res
if __name__ == "__main__":
new, res = main()
if "--미분류" in sys.argv:
c = collections.Counter(re.sub(r"\s+", "", n) for a, b, n in res if a == "미분류")
print(sum(c.values()), len(c))
print(
" ".join(
f"{k}:{v}"
for k, v in c.most_common(int(sys.argv[-1]) if sys.argv[-1].isdigit() else 300)
)
)
sys.exit()
SRC.write_text(new, encoding="utf-8", newline="\n")
OUT_MD.write_text(묶음_md(res), encoding="utf-8", newline="\n")
print("구분·상세구분 채움", len(res), "줄")