카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.
다음은 카카오 아이디의 규칙입니다.
- 아이디의 길이는 3자 이상 15자 이하여야 합니다.
- 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
- 단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.
"네오"는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.
신규 유저가 입력한 아이디가 new_id 라고 한다면,1단계 newid의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.📌 문제
신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, "네오"가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.
📌 제한사항
new_id는 길이 1 이상 1,000 이하인 문자열입니다.
new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.
new_id에 나타날 수 있는 특수문자는 -_.~!@#$%^&*()=+[{]}:?,<>/ 로 한정됩니다.📌 입출력 예
입출력 예 #1
1단계 대문자 'B'와 'T'가 소문자 'b'와 't'로 바뀌었습니다.
"...!@BaT#*..y.abcdefghijklm" → "...!@bat#*..y.abcdefghijklm"2단계 '!', '@', '#', '' 문자가 제거되었습니다.
"**...!@bat#..y.abcdefghijklm" → "...bat..y.abcdefghijklm**"3단계 '...'와 '..' 가 '.'로 바뀌었습니다.
"...bat..y.abcdefghijklm" → ".bat.y.abcdefghijklm"4단계 아이디의 처음에 위치한 '.'가 제거되었습니다.
".bat.y.abcdefghijklm" → "bat.y.abcdefghijklm"5단계 아이디가 빈 문자열이 아니므로 변화가 없습니다.
6단계 아이디의 길이가 16자 이상이므로, 처음 15자를 제외한 나머지 문자들이 제거되었습니다.
"bat.y.abcdefghijklm" → "bat.y.abcdefghi"7단계 아이디의 길이가 2자 이하가 아니므로 변화가 없습니다.
"bat.y.abcdefghi" → "bat.y.abcdefghi"따라서 신규 유저가 입력한 new_id가 "...!@BaT#*..y.abcdefghijklm"일 때, 네오의 프로그램이 추천하는 새로운 아이디는 "bat.y.abcdefghi" 입니다.
입출력 예 #2
1단계 변화 없습니다.
2단계 "z-+.^." → "z-.."
3단계 "z-.." → "z-."
4단계 "z-." → "z-"
5단계 변화 없습니다.
6단계 변화 없습니다.
7단계 "z-" → "z--"
이 문제를 풀기 위해서는 문자열을 요리조리 다루는 방법이 필요하다!
- 소문자로 변환하는 함수 lower()
str = str.lower()
이 함수는 문자열 str의 모든 대문자를 소문자로 변환해 준다.
1단계에서 lower()함수를 사용하였다.
- 문자가 숫자인지 판별하는 함수 isdigit()
c.isdigit()
문자 c가 숫자이면 True, 숫자가 아니면 False를 반환한다.
- 문자가 알파벳인지 판별하는 함수 isalpha()
c.isalpha()
문자 c가 알파벳이면 True, 알파벳이 아니면 False를 반환한다.
문제에서는 '소문자 알파벳'이라는 조건을 주었지만, 1단계에서 이미 모두 소문자로 변환하였기에 2단계에서는 isalpha()함수를 사용하였다.
- 특정 문자열 치환하는 함수 replace()
new_id = new_id.replace('..', '.')
3단계에서 '.'가 2개 이상 나올 경우, '.'한 개로 바꾸기 위해 while 문 안에서 replace()함수를 사용하였다.
- 문자열의 첫번째 문자 제거 (4단계)
new_id = new_id[1:]
- 문자열의 마지막 문자 제거 (4단계)
new_id = new_id[:-1]
+) 문제 제출을 완료한 후, 다른 사람의 풀이를 보았는데 정규식을 이용한 매우 간단한 코드가 있어 참고해서 정리하려구 한다 🤓
import re re.sub(pattern, new_text, text)
: text에서 pattern에 맞는 부분을 new_text로 대체한다
📝 패턴 문자
^: 문자열의 시작을 의미. 또는 not의 의미.
$: 문자열의 끝을 의미
+: 어떤 문자건 1회 이상 반복되는 패턴을 나타냄# 소문자 알파벳, 숫자, -,_,. 제외한 문자는 제거함 st = re.sub('[^a-z0-9\-_.]', '', st) # '.'가 연속 2개 이상일 경우, '.' 하나로 치환함 st = re.sub('\.+', '.', st) # '.'가 처음이나 끝에 위치한다면 제거함 st = re.sub('^[.]|[.]$', '', st)
def solution(new_id): # 1단계 new_id의 모든 대문자를 대응되는 소문자로 치환 new_id = new_id.lower() # print('1단계 -> ', new_id) # 2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거 for c in new_id: if not filter(c): new_id = new_id.replace(c, '') # print('2단계 -> ', new_id) # 3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환 while '..' in new_id: new_id = new_id.replace('..', '.') # print('3단계 -> ', new_id) # 4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거 if new_id[0] == '.': new_id = new_id[1:] if len(new_id) >= 1: # print("new_id[-1] = ", new_id[-1]) if new_id[-1] == '.': new_id = new_id[:-1] # print('4단계 -> ', new_id) # 5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입 if not new_id: new_id = "a" # print('5단계 -> ', new_id) # 6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거 # 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거 if len(new_id) >= 16: new_id = new_id[:15] if new_id[-1] == '.': new_id = new_id[:-1] # print('6단계 -> ', new_id) # 7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙임 if len(new_id) <= 2: while (len(new_id) < 3): new_id = new_id + new_id[-1] # print('7단계 -> ', new_id) return new_id def filter(c): return ((c in ['-','_','.']) or (c.isdigit()) or (c.isalpha()))