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
1 답변
-
re.sub()
는 문자열 치환 하기위해 사용한 것은 아실테고.rename = re.sub("[\(\[].*?[\)\]]", "",name)
[\(\[]
여는 소괄호나 대괄호 중 하나.*?
그 이후에 내부의 어떠한 문자들 lazy 하게 캡쳐[\)\]]
닫는 소괄호나 대괄호 중 하나
여기서 greedy 와 lazy 매칭의 차이를 아셔야 합니다.
수량자 이후에 오는
?
는 와일드카드로써의 의미인직전에 쓰인 문자와 0 또는 1번 일치
의 의미를 가지지 않습니다.
기본적으로 수량자(
*
,+
,?
)만 사용하면 greedy 매칭이 일어납니다. 말그대로 탐욕적이죠. 중간에 매칭되는 것들은 뭐든간 일단 최대한 포함시켜 버립니다. 탐색하는 문자열에서 제일 마지막 종료조건이 만족하는 곳까지 다 이 수량자에 매칭시켜 버리기 때문에,만약 정규표현식에
?
를 뺀 상태인[\(\[].*[\)\]]
이걸 사용하면 위의 1번 문자열은re.sub()
에 의해 이렇게 치환될겁니다.16_Ang.bmp
하지만 이
?
를 뒤에 붙여줌으로써 해당 문법은게으른 수량자
로 동작하게 됩니다.뒤에꺼 다 살펴보긴 싫고 그냥 가장 가까운 걸로 매칭하자
의 의미가 되어버리기 때문에 각 대괄호와 그 안쪽이 제각기 매칭되면서 빈문자열로 치환된 거죠.오히려 치환된 결과를 보면 매우 부지런히 일한 것 처럼 보이지만 사실 수량자 입장에서는 게으름을 피운 겁니다. 바로 눈 앞에 보이는 일만 했으니까요. :)
댓글 입력