파이썬 정규표현식 자신있으신분 질문좀 드려요!
조회수 634회
첫번째 문제
import re
def commaParse(num):
return re.findall('(?=(\d{3}))',num)
a = commaParse('100000000')
print(a)
결과: ['100', '000', '000', '000', '000', '000', '000']
두번째 문제
import re
def commaParse(num):
return re.findall('(?=\d{3})',num)
a = commaParse('100000000')
print(a)
결과: ['', '', '', '', '', '', '']
질문드릴게요. 정말 별것도 아니라고 생각하실수 있는데 아무리 찾아봐도 답이 안나오네요...
일단 컴파일 옵션에서 다른점이 (?=\d{3})
, (?=(\d{3}))
안쪽 괄호가 있냐없냐 차이인데 어떤이유로 결과가 저렇게 다른건지 알고싶구요
첫번째 문제에서 제 예상 답은 긍정 전방탐색으로 ['100', '000', '000']
이 나와야 하는데 왜 저렇게 나오는지를 모르겟네요...
그리고 두번째 문제에서도 긍정형 탐색으로 매치가 되면 빈 문자열을 반환하는 걸로 알고있거든요 그래서 ['', '', '']
이 나올줄 알았는데 왜 더 많이 나올까요....
1 답변
-
positive lookahead.
설명은 어짜피 구글링 하면 매우매우 많이 나오니 생략하고...
word(?=ahead)
word
라는 단어를 찾되, 앞에ahead
라는 단어가 있는word
만 찾는 정규식.작성하신 정규식은
word
에 해당하는 찾고자 하는 패턴이 일단 없음!! 그래서 의도가 불분명한 이상한 정규식이라 볼 수 있습니다.다만 결과가 나오는 것은
(\d{3})
라는 정규식에서()
괄호는 캡쳐링을 의미하기 때문에 이 캡쳐링된 매칭 결과를 값으로 반환해 주기 때문이지, 이건 작성자가 의도한 매칭이 아니라는 것!실제로 전방 탐색을 위한
(?=)
안의 정규식에 대한 매칭 값은 소비하지 않기 때문에 이 후 매칭 진행에도 사용 됩니다.그래서 의도와는 다르게 7개나 매칭되게 됩니다.
만약 의도대로 3개를 찾아서 소비했으면 그 다음 숫자로 넘어가야 하는데 실제 소모는 안 되니까 한 글자씩 앞으로 이동하면서 모든 패턴을 캡쳐하게 되죠. 아래 처럼요.
100
000000- 1
000
00000 - 10
000
0000 - 100
000
000 - 1000
000
00 - 10000
000
0 - 100000
000
질문자분은 실제 찾아야 할 부분을 정규식에 넣지 않았으므로 하이라이트 된 숫자 세개 바로 앞의 빈값(empty string)이 매칭된 부분이라고 보면 됩니다. 하이라이트 된 숫자들은
()
괄호 때문에 캡쳐링 된 부분이므로 결과는 총 7개가 나오게 되죠.그럼 이제 따로 설명하지 않아도 두 번째 시도한
(?=\d{3})
괄호가 없는 이 정규식이 왜 빈값이 7개나 나오는지 이해가 될 것입니다.
원래 의도대로 숫자 3개씩 매칭하려면 그냥
\d{3}
이면 충분함.
댓글 입력