파이썬 정규표현식, 서브그룹이 있을 때 re.findall() 작동방식, 서브그룹과 반복에 대해

초록·2023년 12월 11일
0

서브그룹이 있을 때 findall() 작동방식

최근 정규표현식을 사용하다가 엥 이게 왜 이렇게 되는거지 싶을 때가 종종 있었는데, 알고보니 findall()의 작동방식을 잘 몰라서 그런 거였습니다..!

쉽게 이해할 수 있도록 그림을 그려보았습니다.

findall()은 ()으로 감싸진 '서브그룹'이 없을 땐 모든 매칭결과를 리턴하지만, 서브그룹이 있을 땐 모든 매칭결과의 서브그룹들을 반환합니다.

서브그룹과 반복

제가 서브 그룹 관련해서 어리둥절했던 부분은 아래와 같습니다.

p = "([abc])+"
s = "abc"
print(re.search(p, s).group()) # abc
print(re.search(p, s).groups()) # ('c',) 
print(re.findall(p, s)) # ['c']

([abc])+는 a 혹은 b 혹은 c로 이루어진 1개 이상의 문자열에 매칭됩니다. "abc"를 매칭해보았구요.

아까 서브그룹이 있을 때 findall은 모든 매칭 결과의 서브그룹을 반환한다고 했죠? 그걸 보고 제가 생각했던 건, "abc"([abc])+([abc])에 해당할 수 있는 문자는 a, b, c니까 [a,b,c]가 나오겠다고 생각했습니다.

그런데 findall의 경우 c가 나왔습니다. 왜 하필 c일까요? 확실하진 않지만 제 생각을 말씀드리겠습니다.

위 정규표현식 ([abc])+엔 괄호가 1개 있으니 서브그룹 번호도 1번이고 group(1)로 접근 가능합니다.
그런데, abc 문자열에서 표현식 ([abc])+ 괄호 안의 내용인 [abc]에 해당하는 내용은 a 1글자 혹은 b 1글자 혹은 c 1글자 입니다.
그래서 정규표현식 엔진이 문자열을 훑어감에 따라, a를 읽었을 땐 서브그룹 1번의 내용이 a로, b를 읽었 을 땐 b로, 마지막으로 c를 읽었을 땐 c로 변경되어 최종 group(1)의 내용이 c가 된건 아닌가 짐작합니다.

공식문서에선 해당 내용을 찾아볼 수 없어 아쉽네요.

🔗 파이썬 정규표현식 공식문서 보러가기

profile
몰입하고 성장하는 삶을 동경합니다

0개의 댓글