[2021 KAKAO BLIND RECRUITMENT] 신규 아이디 추천

마리 Mari·2021년 4월 6일
0
post-thumbnail

문제 링크

문제(요약)

입력된 문자를 정해진 조건에 맞도록 변환한 후 반환한다. 조건은 다음과 같다.

  • 아이디의 길이는 3자 이상 15자
  • 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 만 사용 가능
  • 단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속 사용 불가

문제에서 제시된 과정을 통해 입력된 아이디(new_id)를 변환한다. 과정은 다음과 같다.

  1. 대문자를 소문자로 치환
  2. 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자 제거
  3. 2번 이상 연속되는 마침표(.)가 있으면, 한개로 치환
  4. id의 처음이나 끝에 위치한 마침표(.)가 위치하면, 제거
  5. id가 빈 문자열이면, id = "a"
  6. d의 길이가 16자 이상이면, id = [:15]
    제거 후 마침표(.)가 d의 끝에 위치하면, 해당 마침표(.) 제거
  7. id의 길이가 2자 이하면, id의 마지막 문자를 id의 길이가 3이 될 때까지 반복해서 끝에 붙임.

입력된 new_id를 규칙에 맞게 변환한 추천아이디를 return하는 함수 solution 만들기




풀이

정규표현식을 이용하여 풀었다.

0. 정규표현식 모둘 re 불러오기

import re

1.대문자를 소문자로 치환

answer = new_id.lower()

2. 허용되지 않은 문자 제거

answer = re.sub('[^.\-_a-z0-9]', '', answer)

[^.\-_a-z0-9] : 마침표(.), bar(-), underbar(_), 소문자 알파벳, 숫자를 제외한 문자를 의미하는 정규표현식

  • 이 부분에서 계속해서 에러가 났는데, - 가 문자가 아니라 메타문자로 인식되어서 발생한 문제였다.
  • - 는 정규표현식의 문자 클래스의 메타문자로 [a-c] 라고 할 경우 a 부터 c, 즉 a, b, c 중 하나의 문자임을 의미한다.
  • .-_ 부분이 마침표(.)부터 underbar(_)까지로 인식되어 @ 등의 문자가 제거되지 못했다.
  • bar(-)앞에 \를 붙여줌으로 해결

3. 중복되는 마침표(.) 제거

answer = re.sub('[.]{2,}', '.', str(answer))

[.]{2, } : 마침표가 2개 이상인 문자열을 의미하는 정규표현식.

  • 마침표는 정규표현식에서 메타문자(원래 문자가 가진 뜻이 아니라, 문자를 나타내는 용도로 사용되는 문자)로 줄바꿈 문자인 \n을 제외한 모든 문자를 의미한다.
  • 따라서 메타문자로서 마침표가 아니라 문자로서 마침표를 사용하고자 한다면, [.] 와 같이 문자 클래스 안에서 사용해주어야 한다.
  • 문자 뒤에 중괄호를 사용하여 문자의 반복 횟수의 범위를 정할 수 있다. {n,m} 이면 n이상 m이하를 의미한다. 위의 정규표현식의 {2, }는 2개 이상을 의미한다.

4. 시작과 끝 위치의 마침표(.) 제거

answer = re.sub('^[.]+|[.]+$', '', str(answer))

^[.]+|[.]+$ : ^[.]+ OR [.]+$, 시작이 마침표 1개 이상으로 시작하거나, 끝이 마침표 1개 이상으로 끝나는 경우를 의미하는 정규표현식

  • ^[.]+ : ^는 문자열의 시작 부분을 의미. +는 앞의 문자가 한개 이상, 즉 {1,}과 동일한 의미
    => 시작점의 마침표가 1개 이상
  • | : OR
  • [.]+$ : $는 문자열의 끝 부분을 의미
    => 끝점의 마침표가 1개 이상

5. 빈 문자 체크, 'a' 대입

if len(answer) == 0 : answer = 'a'

6. 문자열 길이가 16 이상이면, 15번째 문자까지만 남기기

남긴 후 시작/끝점 마침표 체크

if len(answer) > 15 : 
	answer = answer[:15]
	answer = re.sub('^[.]+|[.]+$', '', str(answer))

7. 문자열 길이가 2 이하이면, 길이가 3이 될 때 까지 마지막 문자를 문자열 뒤에 더하기

if len(answer) < 3 : answer += answer[-1] * (3 - len(answer))



전체 코드

def solution(new_id):
    import re
    
    answer = new_id.lower()
    
    answer = re.sub('[^.\-_a-z0-9]', '', answer)
    answer = re.sub('[.]{2,}', '.', str(answer))
    answer = re.sub('^[.]+|[.]+$', '', str(answer))
    
    if len(answer) == 0 : answer = 'a'
    if len(answer) > 15 :  
        answer = answer[:15]
        answer = re.sub('^[.]+|[.]+$', '', str(answer))
    if len(answer) < 3 : answer +=  answer[-1] * (3 - len(answer)) 
    
    return answer

정규표현식 자꾸 까먹어서 쓸 때마다 자꾸 공부했던 자료를 다시 들춰보게 된다.
이번 기회로 다시 익숙해지는 기회를 가져서 좋았다.
이젠 진짜 안까먹어야지... 아자아자.. ^ __ ^ ) 9





참고 자료

점프 투 파이썬 - 07-3. 강력한 정규 표현식의 세계로


profile
우리 블로그 정상영업합니다.

0개의 댓글