문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/72410
처음 작성한 코드
- 단계별로 문자열을 수정하는 풀이이다.
- 1단계는 lower 함수를 이용해서 알파벳을 모두 소문자로 바꾸어 주었다.
- 2단계는 소문자, 숫자, '-_.' 3가지의 특수문자를 허용해주어야 하는데, 반대로 안 되는 문자를 제거했다.
- 3단계는 정규표현식을 이용했는데, 다른 코드 항목에서 설명하겠다.
- 4단계는 문자열의 첫 혹은 마지막 부분이 '.'임을 확인해야하는데, [0] 혹은 [-1]로 찾을 시에 빈 문자열에서는 오류를 발생시키므로, [:1] 혹은 [-1:]로 범위를 지정하여 빈 문자열에서도 오류 없이 작동시키게 하자
- 5단계는 빈 문자열일 경우 'a'로 치환한다.
- 6단계는 문자열의 길이가 16일 경우 슬라이싱을 이용하여 15자로 제한한다.
- 7단계에서는 문자열의 길이가 3이 될때까지 마지막 문자를 중복하여 더해준다.
def solution(new_id):
# 1단계
new_id = new_id.lower()
# 2단계
for c in "~!@#$%^&*()=+[{]}:?,<>/":
new_id = new_id.replace(c, '')
# 3단계
import re
new_id = re.sub('([.]{2,})', '.', new_id)
# 4단계
if new_id[:1] == '.':
new_id = new_id[1:]
if new_id[-1:] == '.':
new_id = new_id[:-1]
# 5단계
if new_id == '':
new_id = 'a'
# 6단계
if len(new_id) >= 16:
new_id = new_id[:15]
if new_id[-1:] == '.':
new_id = new_id[:-1]
# 7단계
while len(new_id) < 3:
new_id += new_id[-1]
return new_id
# 입출력 예시
print(solution( "...!@BaT#*..y.abcdefghijklm"))
print(solution( "z-+.^."))
print(solution("=.="))
print(solution("123_.def"))
print(solution("abcdefghijklmn.p"))
2단계의 코드는 아래와 같이 허용한 글자만 통과시키는 것이 더욱 올바르다.
for c in new_id:
if c.isalpha() or c.isdigit() or c in ['-', '_', '.']:
answer += c
3단계의 코드를 정규표현식을 쓰지 않고 작성한다면 아래와 같이 while문으로 표현할 수 있다.
while '..' in answer:
answer = answer.replace('..', '.')
문자열을 많이 다루는 문제를 보니 정규표현식을 정확히 알고 잘 쓰는것이 중요하다 느꼈다.
위키, 정리글, 예제로 쉽게보는 가이드를 참고하며 배우면 도움이 크게 될 것이다.
https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%ED%91%9C%ED%98%84%EC%8B%9D
https://gocoding.tistory.com/93
https://school.programmers.co.kr/learn/courses/11/11-%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D
다른 코드
[코드1]
- 최대한 정규표현식을 이용해 표현해 보았다.
- 2단계에서 대괄호와 -를 이용해 소문자, 숫자, 그리고 특수 문자 3개를 지정해 주었다.
- '^'를 대괄호 안 처음에 선언해 주면 지정한 문자를 제외하는 의미가 된다.
- 따라서 지정한 문자를 제외한 나머지 문자는 제거하게 된다.
- 3단계에서는 지정한 문자 '.'을 중괄호 {}를 통해 2번 이상, 그리고 최댓값 제한 없이 나올 시에 '.'하나로 치환하였다.
- 4단계에서는 지정한 문자 대괄호 앞에 '^'를 넣음으로써 처음에 나오는 '.'을 지정해주었고, 대괄호 뒤에 '$'을 넣음으로서 마지막에 나오는 '.'을 지정해 주었다.
- 두 가지 경우를 모두 포함해야 하므로, or 연산자 '|'를 중간에 삽입해 준다.
- 두 가지 경우에 대해 문자는 제거된다.
- 6단계에서는 조건문 사용 없이 슬라이싱을 통하여 나누어도 문제가 발생하지 않는다.
- 4단계에서 사용한 '$'를 이용해 마지막에 나오는 '.'을 제거하게 된다.
- 7단계에서는 루프문을 사용하지 않고 ljust 함수를 이용하여 문자를 채웠다.
- ljust 함수는 문자를 좌로 정렬하고, 지정된 문자열의 길이보다 작을 시에 지정한 문자로 공백을 채운다.
import re
def solution(new_id):
# 1단계
new_id = new_id.lower()
# 2단계
new_id = re.sub('[^a-z0-9\-_.]', '', new_id)
# 3단계
new_id = re.sub('([.]{2,})', '.', new_id)
# 4단계
new_id = re.sub('^[.]|[.]$', '', new_id)
# 5단계
if new_id == '':
new_id = 'a'
# 6단계
new_id = re.sub('[.]$', '', new_id[:15])
# 7단계
new_id = new_id.ljust(3, new_id[-1])
return new_id
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[Programmers][Python] 실패율 (0) | 2023.04.03 |
---|---|
[Programmers][Python] 추억 점수 (0) | 2023.03.31 |
[Programmers][Python] 신고 결과 받기 (0) | 2023.03.29 |
[Programmers][Python] 성격 유형 검사하기 (0) | 2023.03.29 |
[Programmers][Python] 햄버거 만들기 (0) | 2023.03.27 |