re.sub 질문이요

조회수 744회
import glob

import shutil

import os

import re

dirs = ['DataGathering']

for dir in dirs:

   file_names = glob.glob(os.path.join(dir,'*'))

file_names = [os.path.basename(name) for name in file_names]

   if not os.path.exists(dir +'_renamed'):

       os.makedirs(dir+'_renamed')

       #os.makedirs(dir+'_renamed/csv')

   root = dir + '_renamed'

   for name in file_names:

     if name.endswith('csv') :
           continue
       print(name)
       rename = re.sub("[\(\[].*?[\)\]]", "",name)

re.sub을 보시면 굉장히 복잡하게 되어있는데 왜 저기 있는 기호 들이 [] 대괄호 안에 있는 문자들을 포함에 대괄호 자신이 없어지는지 궁금합니다. 원리가 어떻게 되는지 가르쳐 주시면 감사하겠습니다. 1번이 2번처럼 변환됩니다.

1. [Arr]2_[Crd]C1_[Pkg]CAPACITOR-X7R-104K-50V-1608_[PkgType]1_[Conf]_[AF]1_[RBF]1_[CH]1111111111111111_[Type]16_Ang.bmp
2.                2_C1_CAPACITOR-X7R-104K-50V-1608_1__1_1_1111111111111111_16_Ang.bmp
  • digda 님의 편집요청 수락해 주시면 어떨까요. 코드 부분이 지져분합니다. nowp 2019.5.17 11:50

1 답변

  • 좋아요

    3

    싫어요
    채택 취소하기

    re.sub()는 문자열 치환 하기위해 사용한 것은 아실테고.

    rename = re.sub("[\(\[].*?[\)\]]", "",name)
    
    • [\(\[] 여는 소괄호나 대괄호 중 하나
    • .*? 그 이후에 내부의 어떠한 문자들 lazy 하게 캡쳐
    • [\)\]] 닫는 소괄호나 대괄호 중 하나

    여기서 greedy 와 lazy 매칭의 차이를 아셔야 합니다.

    수량자 이후에 오는 ?는 와일드카드로써의 의미인

    직전에 쓰인 문자와 0 또는 1번 일치

    의 의미를 가지지 않습니다.

    기본적으로 수량자(*, +, ?)만 사용하면 greedy 매칭이 일어납니다. 말그대로 탐욕적이죠. 중간에 매칭되는 것들은 뭐든간 일단 최대한 포함시켜 버립니다. 탐색하는 문자열에서 제일 마지막 종료조건이 만족하는 곳까지 다 이 수량자에 매칭시켜 버리기 때문에,

    만약 정규표현식에 ?를 뺀 상태인 [\(\[].*[\)\]] 이걸 사용하면 위의 1번 문자열은 re.sub()에 의해 이렇게 치환될겁니다.

    16_Ang.bmp

    하지만 이 ?를 뒤에 붙여줌으로써 해당 문법은 게으른 수량자로 동작하게 됩니다. 뒤에꺼 다 살펴보긴 싫고 그냥 가장 가까운 걸로 매칭하자 의 의미가 되어버리기 때문에 각 대괄호와 그 안쪽이 제각기 매칭되면서 빈문자열로 치환된 거죠.

    오히려 치환된 결과를 보면 매우 부지런히 일한 것 처럼 보이지만 사실 수량자 입장에서는 게으름을 피운 겁니다. 바로 눈 앞에 보이는 일만 했으니까요. :)

    • 너무너무 감사합니다!!!!! 일하고 있는데 만들어진 툴 중 저부분만 너무 궁금해서 질문드렸습니다.!! 디그다님 곧 진화하시겠네요 자주 출몰해주시길 바랍니다 :D 김한 2019.5.16 17:42
    • 닥트리오는 인싸라서... 저는 아싸라서 진화 못할듯요. 도움이 되었다니 다행입니다. doodoji 2019.5.16 19:56

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

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

(ಠ_ಠ)
(ಠ‿ಠ)