파이썬 정규표현식 자신있으신분 질문좀 드려요!

조회수 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 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    positive lookahead.

    설명은 어짜피 구글링 하면 매우매우 많이 나오니 생략하고...

    word(?=ahead)

    word라는 단어를 찾되, 앞에 ahead 라는 단어가 있는 word만 찾는 정규식.

    작성하신 정규식은 word에 해당하는 찾고자 하는 패턴이 일단 없음!! 그래서 의도가 불분명한 이상한 정규식이라 볼 수 있습니다.

    다만 결과가 나오는 것은 (\d{3})라는 정규식에서 ()괄호는 캡쳐링을 의미하기 때문에 이 캡쳐링된 매칭 결과를 값으로 반환해 주기 때문이지, 이건 작성자가 의도한 매칭이 아니라는 것!

    실제로 전방 탐색을 위한 (?=)안의 정규식에 대한 매칭 값은 소비하지 않기 때문에 이 후 매칭 진행에도 사용 됩니다.

    그래서 의도와는 다르게 7개나 매칭되게 됩니다.

    만약 의도대로 3개를 찾아서 소비했으면 그 다음 숫자로 넘어가야 하는데 실제 소모는 안 되니까 한 글자씩 앞으로 이동하면서 모든 패턴을 캡쳐하게 되죠. 아래 처럼요.

    • 100000000
    • 100000000
    • 100000000
    • 100000000
    • 100000000
    • 100000000
    • 100000000

    질문자분은 실제 찾아야 할 부분을 정규식에 넣지 않았으므로 하이라이트 된 숫자 세개 바로 앞의 빈값(empty string)이 매칭된 부분이라고 보면 됩니다. 하이라이트 된 숫자들은 ()괄호 때문에 캡쳐링 된 부분이므로 결과는 총 7개가 나오게 되죠.

    그럼 이제 따로 설명하지 않아도 두 번째 시도한 (?=\d{3}) 괄호가 없는 이 정규식이 왜 빈값이 7개나 나오는지 이해가 될 것입니다.


    원래 의도대로 숫자 3개씩 매칭하려면 그냥 \d{3} 이면 충분함.

    • 첨언드리면 질문 제목과 내용이 너무 자극적임;; 답변 쓰는 내내 기분이 별로 좋지 않았으며 애초에 누군가의 숙제나 퀴즈를 대신 해 주는 느낌 또한 받아서 쓸까 말까 고민 많이 함... 그래도 답변을 단 것은, 혹시나 다른 비슷한 문제를 겪고 있는 분들이 참고하거나 도움을 얻고 갈 수 있을까 해서입니다. 질문자 분을 위한건 아님. doodoji 2019.9.3 21:34

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)