Python에서 5100개 키워드 포함 여부 빠르게 검사하기
대규모 로그 처리나 텍스트 분석을 하다 보면, 한 문장에 수천 개의 키워드 중 하나라도 포함되어 있는지 빠르게 확인해야 할 때가 있습니다. 단순히 re.search를 5100번 반복하는 방식은 성능이 매우 떨어지므로, 더 효율적인 방법을 소개합니다.
❌ 잘못된 접근: [...] 문자 클래스
정규식에서 [...]는 문자 클래스로 동작합니다.
예: [abc] → "a" 또는 "b" 또는 "c"라는 단일 문자 매치.
따라서 5100개의 키워드를 [...] 안에 넣는 것은 "5100개의 문자열 중 하나"가 아니라 "5100개의 문자 중 하나"를 찾는 것에 불과합니다.
✅ 올바른 접근 방법
1. Set 기반 검색
# 5100개 키워드 준비
keywords = ["error", "warning", "critical", "timeout", "failed", ...]
keywords_set = {k.lower() for k in keywords} # 모두 소문자로 변환
sentence = "System reported CRITICAL failure at 12:00"
# 방법 1: 단어 단위 검색
words = set(sentence.lower().split())
if words & keywords_set:
print("포함됨 (단어 단위)")
# 방법 2: 문장 전체에서 부분 문자열 검색
if any(k in sentence.lower() for k in keywords_set):
print("포함됨 (부분 문자열)")
- 단어 단위 검색: 로그가 공백으로 구분된 경우 최적
- 부분 문자열 검색: 문장 내 임의 위치 검색 가능
2. Aho-Corasick 알고리즘
import ahocorasick
keywords = ["error", "warning", "critical", "timeout", "failed", ...]
keywords = [k.lower() for k in keywords]
A = ahocorasick.Automaton()
for idx, keyword in enumerate(keywords):
A.add_word(keyword, (idx, keyword))
A.make_automaton()
sentence = "System reported CRITICAL failure"
for end_index, (idx, keyword) in A.iter(sentence.lower()):
print("포함:", keyword)
break # 하나라도 찾으면 종료
- 대규모 키워드 검색에 가장 빠른 방법
- 대소문자 무시: 키워드와 문장을 모두 .lower() 처리
3. OR 정규식
import re
keywords = ["error", "warning", "critical", "timeout", "failed", ...]
pattern = re.compile("|".join(map(re.escape, keywords)), re.IGNORECASE)
sentence = "System reported CRITICAL failure"
if pattern.search(sentence):
print("포함됨")
⚠️ 단점: 5100개 키워드라면 정규식이 너무 커져 성능 저하 가능.
📊 방법 비교
| 방법 | 속도 | 메모리 | 적합 상황 |
|---|---|---|---|
| Set 검색 | 빠름 | 중간 | 단순 포함 여부 |
| Aho-Corasick | 매우 빠름 | 중간 | 대규모 키워드 검색 |
| OR 정규식 | 중간 | 높음 | 키워드 수 적을 때 |
🎯 결론
- 5100개 키워드라면 [] 안에 넣는 건 잘못된 방식입니다.
- 실제로는 Set 검색 또는 Aho-Corasick을 쓰는 것이 최적입니다.
- 로그 분석, 보안 탐지, 대규모 텍스트 필터링에 특히 유용합니다.
댓글 없음:
댓글 쓰기