본문 바로가기

카테고리 없음

Python 정규표현식

현업에서 정규표현식이 많이 쓰인다고 한다. 

 

이러한 상황을 가정하고 정규표현식으로 코딩을 해보자. 

 

- 어떤 이커머스 회사에서, 고객이 문의글을 작성했는데 그 글에 고객의 개인정보가 포함되어 있는 경우가 많은거다. 

 

- 그래서 이런 개인정보가 포함되어 있을때, 주민번호는 뒷자리를 *******로 표시하고 전화번호 같은경우 마지막 뒤 4자리를 **** 이렇게 자동으로 바꿔주는 그러한 코드를 짜보자. 

 

# 고객 문의 사항 예시
data = """
안녕하세요!
쿠팡의 제품을 항상 저를 만족시킵니다. 다이소도 좋아요.
3대 500을 찍기 위해서 상당히 잘 사용하고 있는데 제가 샀던 스트랩이 재입고 될 수 있는지 궁금합니다.
제 이름은 홍길동이고 주민번호는 900101-1234567 이며 전화번호는 010-1234-5678 입니다. 
재입고가 된다면 저에게 꼭 연락을 주시고, 주민번호는 왜 남겼는지 모르겠습니다.
확인 부탁드립니다!
"""

 

이런식으로 약간 맥락없고 킹받는 문의글이 있다고 해보자. 

 

코드는 어떻게 짜면 좋을까 ??

 

1. 먼저 저 긴 글의 단어들을 쪼갠다. 

 

2. 그리고 주민번호는 -를 포함시 14개의 글자로 표현되므로 14개 글자로 이어진 부분이 있다면 "-"로 구분하고 "-"를 기준으로 앞부분 뒷부분이 모두 숫자라면 주민번호라고 인식 후 뒷자리 7자를 *******로 바꿔주기. 

 

3. 핸드폰 번호도 13개의 글자이면 궁예 들어가고, -로 구분하여 3, 3, 4 이 부분들이 모두 숫자라면 전화번호라고 인식후 마지막 4자리를 ****로 처리.

 

4. 바꿀 문자들은 별도의 변수로 받고, 그리고나서 다시 문자열들을 합쳐주자. 

 

 

result = []
tmp = ''
for line in data.split("\n"): # \n : 개행문자, 줄바꿈을 의미
    word_result = []
    for word in line.split(' '):
        if len(word)==14 and word[:6].isdigit() and word[-7:].isdigit():
            word = word[:6]+"-*******"
        elif len(word)==13 and word[:3].isdigit() and word[4:8].isdigit() and word[9:].isdigit():
            word = word[:9]+"****"
        word_result.append(word)
    result.append(" ".join(word_result))
print("\n".join(result))

 

두 가지 if문을 통해서 걸렀고 결과는 잘 나오는데, 만약에 고객이 띄어쓰기를 아예 안하는 사람이라면, len() ~~ 13 14를 통해서 거를 순 없다. (고객님들 띄어쓰기 잘해줘요)

 

나는 join 매서드에 대해서 잘 몰랐다. 짚고 넘어가자. 

# 리스트의 요소를 공백을 이용하여 하나의 문자열로 합침

my_list = ['apple', 'banana', 'orange', 'grape']
result = ' '.join(my_list)
print(result)  # 출력: apple banana orange grape
# 튜플의 요소를 쉼표를 이용하여 하나의 문자열로 합침
my_tuple = ('John', 'Doe', '30')
result = ', '.join(my_tuple)
print(result)  # 출력: John, Doe, 30

.join 바로 앞에있는 ' ' 안에있는 친구가 구분자 역할을 해주는 것이다. '11'.join(my_list) 해주면 요소 사이사이마다  11이 붙게된다.

 

지금 for문이 두 개 있는 상황이라 word를 통해서 모든 단어들을 다 검사하고 있다. 단어들은 두 번째 for문 안에있는 ' '공백을 기준으로 split하여 리스트로 담겨있는 그 안에서 도는거다. 

 

data.split('\n')를 출력해보면 

['', '안녕하세요!', '쿠팡의 제품을 항상 저를 만족시킵니다. 다이소도 좋아요.', 
'3대 500을 찍기 위해서 상당히 잘 사용하고 있는데 제가 샀던 스트랩이 재입고 될 수 있는지 궁금합니다.',
'제 이름은 홍길동이고 주민번호는 900101-1234567 이며 전화번호는 010-1234-5678 입니다. ',
'재입고가 된다면 저에게 꼭 연락을 주시고, 주민번호는 왜 남겼는지 모르겠습니다.',
'확인 부탁드립니다!', '']

이렇게 리스트 안에 많은 요소들이 있는 것이다. 맨 윗줄 for문엔 줄바꿈을 기준으로 split하여 리스트로 넣었다.

 

2차 for문에서는 line.split(' ')을 통해 한 줄 한 줄마다 공백을 기준으로 단어들을 검사한다. 

 

2차 for문 안의 word를 통해 조건식 2개를 돌아 나오면 word 하나하나를 다시 word_result로 넣어주고 있다. 

for문 다 돌고 다 들어간 word_result를 출력해보면, 

['']
['안녕하세요!']
['쿠팡의', '제품을', '항상', '저를', '만족시킵니다.', '다이소도', '좋아요.']
['3대', '500을', '찍기', '위해서', '상당히', '잘', '사용하고', '있는데', '제가', '샀던', '스트랩이', '재입고', '될', '수', '있는지', '궁금합니다.']
['제', '이름은', '홍길동이고', '주민번호는', '900101-*******', '이며', '전화번호는', '010-1234-****', '입니다.', '']
['재입고가', '된다면', '저에게', '꼭', '연락을', '주시고,', '주민번호는', '왜', '남겼는지', '모르겠습니다.']
['확인', '부탁드립니다!']
['']

이렇게 줄바꿈하면서 리스트안에 넣어주었다. 한 줄 한줄이 다 리스트다. 6개의 리스트가 word_result안에 담겨있다. 

 

" ".join(word_result)

이것은 join을 통해서 리스트의 각 요소들을 공백을 기준으로 합쳐서 하나의 문자열로 만든다. 단어들 사이엔 공백이 생기게 됨. 이것을 다시 result에 append를 통해서 계속 들어감. 

 

최종적으로 result안에는 각 죽의 단어들이 공백을 통해 모두 들어간 문자열이 저장됨.