Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
@@ -35,6 +35,7 @@ NAME_ENTITY_EXCEPTIONS = set([
|
|
35 |
'법적', '군의', '사회적', '심리적', '행정적', '의료적', '법률적',
|
36 |
'개인정보', '본인', '해당', '현재', '아래', '위치', '소속'
|
37 |
])
|
|
|
38 |
REGEX_KEYWORDS_TO_MASK = set([
|
39 |
'이메일', '전화번호', '연락처', '주소', '센터', '카드번호', '주민등록번호', 'IP', 'IP주소'
|
40 |
])
|
@@ -96,27 +97,6 @@ def mask_department(text):
|
|
96 |
text = re.sub(r"([가-힣]{2,20}학과)", lambda m: to_chosung(m.group(1)[:-2]) + "학과", text)
|
97 |
return text
|
98 |
|
99 |
-
def mask_sensitive_numbers(text):
|
100 |
-
# 일반 전화번호: 000-0000-0000
|
101 |
-
text = re.sub(r"(\d{2,3})-(\d{3,4})-(\d{4})", r"\1-****-\3", text)
|
102 |
-
# 주민등록번호
|
103 |
-
text = re.sub(r"(\d{6})[-](\d)\d{6}", r"*******-\2*****", text)
|
104 |
-
# 카드 번호
|
105 |
-
text = re.sub(r"(\d{4})[- ]?(\d{4})[- ]?(\d{4})[- ]?(\d{4})", r"\1-****-****-\4", text)
|
106 |
-
# 번지/동/호
|
107 |
-
text = re.sub(r"(\d{1,3})번지", r"***번지", text)
|
108 |
-
text = re.sub(r"(\d{1,3})동", r"***동", text)
|
109 |
-
text = re.sub(r"(\d{1,4})호", r"****호", text)
|
110 |
-
# 이메일
|
111 |
-
text = re.sub(r"[\w\.-]+@[\w\.-]+", r"******@****", text)
|
112 |
-
# IP 주소
|
113 |
-
text = re.sub(r"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})", r"\1.\2.*.*", text)
|
114 |
-
|
115 |
-
# ✅ 여기서 짝수 세트만 마스킹
|
116 |
-
text = mask_even_numbered_numeric_sets(text)
|
117 |
-
|
118 |
-
return text
|
119 |
-
|
120 |
def sanitize_sensitive_info(text, keyword_string, replace_word):
|
121 |
text = mask_school_names(text)
|
122 |
text = mask_department(text)
|
@@ -130,7 +110,16 @@ def sanitize_sensitive_info(text, keyword_string, replace_word):
|
|
130 |
pattern = rf"\b{re.escape(kw)}\b"
|
131 |
text = re.sub(pattern, replace_word, text, flags=re.IGNORECASE)
|
132 |
|
133 |
-
text =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
return text
|
135 |
|
136 |
def final_name_remask_exact_only(text, mapping_dict):
|
@@ -179,16 +168,17 @@ def apply_masking(text, keywords, replace_word):
|
|
179 |
|
180 |
with gr.Blocks() as demo:
|
181 |
gr.Markdown("""
|
182 |
-
🛡️
|
183 |
-
이름 +
|
|
|
184 |
""")
|
185 |
-
input_text = gr.Textbox(lines=15, label="
|
186 |
-
keyword_input = gr.Textbox(lines=1, label="기관 키워드", value="
|
187 |
-
replace_input = gr.Textbox(lines=1, label="
|
188 |
-
run_button = gr.Button("🚀
|
189 |
-
masked_output = gr.Textbox(lines=15, label="🔐
|
190 |
-
mapping_output = gr.Textbox(lines=10, label="🏷️ 이름 태그
|
191 |
|
192 |
run_button.click(fn=apply_masking, inputs=[input_text, keyword_input, replace_input], outputs=[masked_output, mapping_output])
|
193 |
|
194 |
-
demo.launch()
|
|
|
35 |
'법적', '군의', '사회적', '심리적', '행정적', '의료적', '법률적',
|
36 |
'개인정보', '본인', '해당', '현재', '아래', '위치', '소속'
|
37 |
])
|
38 |
+
|
39 |
REGEX_KEYWORDS_TO_MASK = set([
|
40 |
'이메일', '전화번호', '연락처', '주소', '센터', '카드번호', '주민등록번호', 'IP', 'IP주소'
|
41 |
])
|
|
|
97 |
text = re.sub(r"([가-힣]{2,20}학과)", lambda m: to_chosung(m.group(1)[:-2]) + "학과", text)
|
98 |
return text
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
def sanitize_sensitive_info(text, keyword_string, replace_word):
|
101 |
text = mask_school_names(text)
|
102 |
text = mask_department(text)
|
|
|
110 |
pattern = rf"\b{re.escape(kw)}\b"
|
111 |
text = re.sub(pattern, replace_word, text, flags=re.IGNORECASE)
|
112 |
|
113 |
+
text = re.sub(r"(\d{3})-(\d{4})-(\d{4})", r"\1-****-\3", text)
|
114 |
+
text = re.sub(r"(\d{4})년 (\d{1,2})월 (\d{1,2})일", r"19**년 \2월 *일", text)
|
115 |
+
text = re.sub(r"(\d{1,3})번지", r"***번지", text)
|
116 |
+
text = re.sub(r"(\d{1,3})동", r"***동", text)
|
117 |
+
text = re.sub(r"(\d{1,4})호", r"****호", text)
|
118 |
+
text = re.sub(r"[\w\.-]+@[\w\.-]+", r"******@****", text)
|
119 |
+
text = re.sub(r"(\d{6})[-](\d)\d{6}", r"*******-\2*****", text)
|
120 |
+
text = re.sub(r"([가-힣]+(대로|로|길))\s?(\d+)(호|번길|가)?", r"\1 ***", text)
|
121 |
+
text = re.sub(r"(\d{4})[- ]?(\d{4})[- ]?(\d{4})[- ]?(\d{4})",
|
122 |
+
lambda m: f"{m.group(1)}-****-****-{m.group(4)}", text)
|
123 |
return text
|
124 |
|
125 |
def final_name_remask_exact_only(text, mapping_dict):
|
|
|
168 |
|
169 |
with gr.Blocks() as demo:
|
170 |
gr.Markdown("""
|
171 |
+
🛡️ **민감정보 마스킹 [땡땡이 마스킹]**
|
172 |
+
이름 + 민감정보 + 초/중/고 마스킹기 (초성 기반)
|
173 |
+
⚠️ *완벽하지 않을 수 있습니다. 반드시 직접 최종 점검하세요.*
|
174 |
""")
|
175 |
+
input_text = gr.Textbox(lines=15, label="📥 원본 텍스트 입력")
|
176 |
+
keyword_input = gr.Textbox(lines=1, label="기관 키워드 (쉼표로 구분)", value="굿네이버스, good neighbors, gn, 사회복지법인 굿네이버스")
|
177 |
+
replace_input = gr.Textbox(lines=1, label="치환할 텍스트", value="우리기관")
|
178 |
+
run_button = gr.Button("🚀 마스킹 실행")
|
179 |
+
masked_output = gr.Textbox(lines=15, label="🔐 마스킹된 텍스트")
|
180 |
+
mapping_output = gr.Textbox(lines=10, label="🏷️ 이름 태그 매핑", interactive=False)
|
181 |
|
182 |
run_button.click(fn=apply_masking, inputs=[input_text, keyword_input, replace_input], outputs=[masked_output, mapping_output])
|
183 |
|
184 |
+
demo.launch()
|