Python re 모듈 의 함정: Catastrophic Backtracking

2024. 11. 24. 11:23카테고리 없음

3줄 요약

정규표현식(regex) 을 Language Model의 결과를 후처리하고 있습니다. 특히 hallucination 을 필터링하는 데 유용하게 쓰고 있는데요, regex 에서도 무한루프가 걸릴 수 있답니다! (저는 몰랐고 알고 싶지 않았습니다) 

이런 regex 의 무한루프에 대해 알아보고 python 에서 해결방법을 구현해 보았습니다.

 

 

 

Regex

정규표현식은 Regular Expression 으로, 문자열에서 특정 패턴을 찾고, 대체하고, 분할하는 데 사용합니다.

대표적인 사용처는

- 데이터 유효성 검사 (ID, PW, 이메일 주소, 전화번호 등)

- 데이터셋 전처리

 

등이 있습니다.

 

 

python에서 정규표현식은 내장 모듈인 re를 대부분 이용합니다.

이 re 모듈의 사용예시를 간단히 살펴보면 아래와 같이 이메일 주소의 형식을 검증하고, 형식에서 벗어나는 내용을 필터링해서 리턴합니다.

 

import re
pattern = r'[^a-zA-Z0-9._%+-@]'
myemail = 'myemail오타@gmail틀림.com'

re.sub(pattern, '', myemail)

 

regex101 사이트를 이용해서도 간편히 체크할 수 있습니다

 

 

 

Catastrophic Backtracking

그러나 regex 필터링은 반복되는 글자가 있을 때 hang이 발생할 수 있습니다. 특히 .* 나 .+ 이 사용되는 경우에 주의가 필요합니다. 정규표현식에서 .*는 탐욕적 반복자 로서 해당 패턴을 가능한 많이 매치시키려고 하기 때문입니다. 

 

 

Language Model 이 흔하게 발생시키는 hallucination 인 무의미한 글자 반복의 예시를 들어보겠습니다.

pattern = '(아니.*)+아니$'
text = '아니...아니...아니... 아니...아니...아니... 아니...아니...아니... 아니...아니...아니... 아니...아니...아니... 아니...아니...아니... 아니...'

 

 

regex101 사이트 우측 상단에 'catastrophic backtracking' 이라고 표시되는 것을 볼 수 있습니다.

 

 

javascript 공식문서 에서는 catastrophic backtracking 을 피하는 두 가지 방법을 제시합니다. 

- 가능한 조합의 갯수 줄이기: 정규표현식을 최대한 효율적으로 작성하세요

- backtracking 예방하기: .* .+ 같은 greedy search 를 최대한 지양하고, 반복횟수에 제한을 두세요.

 

 

그러나 hallucination 을 후처리하기 위한 목적으로는 슬프게도 두 가지 방법 모두 사용이 어렵습니다 😂

 

해결방법

python 내장모듈 re가 아닌 pypi의 서드파티 모듈인 regex는 연산에서 타임아웃을 지원합니다.

 

아래 모듈을 사용할 환경에 설치하고

pip install regex

 

 

실습용 스크립트를 실행하면 실행시간이 1ms 가 넘어가기 때문에 자동으로 timeout 을 실행시켜 무한루프를 방지해 줍니다.

import regex as re

pattern = '(아니.*)+아니$'
text = '아니...아니...아니... 아니...아니...아니... \
아니...아니...아니... 아니...아니...아니...  아니...아니... \
아니... 아니...아니...아니... 아니...아니...아니...아니... \
아니...아니...아니... 아니...아니...아니... 아니...아니... \
아니... 아니...아니...아니... 아니...아니...아니... 아니...\ 
아니...아니...아니... 아니...아니...아니... 아니...아니...\
아니... 아니...아니...아니... 아니... 아니...아니... 
아 니...아니...아니... 아니...'

re.sub(pattern, '', text, timeout=0.001)

 

 

 

무한루프 없는 정규표현식 사용에 도움이 되시기를 바랍니다 🙃

 

 

 

참고문헌

https://medium.com/bigpanda-engineering/catastrophic-backtracking-the-dark-side-of-regular-expressions-80cab9c443f6

https://ko.javascript.info/regexp-catastrophic-backtracking