개발하는 일상

프로그래머스 신규 아이디 추천 javascript 정규식(regex) 해설 본문

개발 간단 팁

프로그래머스 신규 아이디 추천 javascript 정규식(regex) 해설

롯데빙빙바 2021. 3. 28. 17:25

문제링크: programmers.co.kr/learn/courses/30/lessons/72410

문제

입력으로 받은 문자열 new_id를 다음 단계에 맞게 바꾸어 추천아이디를 만드는 문제입니다.

1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
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이 될 때까지 반복해서 끝에 붙입니다.

답안 코드

저는 정규식을 잘 몰라서 조건식을 일일이 써 가면서 풀었는데, 다른 분들의 풀이를 보고 정규식을 잘 사용하면 코드를 간결히 쓸 수 있다는 점을 느끼고 자세한 해설을 작성해보았습니다. 코드는 Alex_choi, bbinbbin, papa님의 코드를 참고하여 작성하였습니다.

function solution(new_id) {
    const answer = new_id
        .toLowerCase() // 1
        .replace(/[^\w-_.]/g, '') // 2
        .replace(/\.+/g, '.') // 3
        .replace(/^\.|\.$/g, '') // 4
        .replace(/^$/, 'a') // 5
        .slice(0, 15).replace(/\.$/, ''); // 6
    return answer.padEnd(3, answer[answer.length-1]); // 7
}

1단계

toLowerCase(): 문자열을 모두 소문자로 바꿔 리턴하는 메소드입니다.

2단계

replace(searchValue:string|RegExp, replaceValue: string): string: 첫 번째 인자로 교체 대상이 되는 문자열이나 정규식 인스턴스를 받고, 두 번째 인자로 교체되어 들어갈 문자열을 받습니다. 교체된 문자열을 리턴합니다.
/정규식/: javascript에서 정규식을 작성할 때 이와 같은 형태로 작성합니다.
[문자셋]: []안에 들어가는 문자열은 문자셋이라고 하고, . 이나 *과 같은 정규식의 특수문자가 특수문자 취급 받지 않고 문자 그대로 취급받습니다.
\w: [A-Za-z0-9_]와 동일합니다. 영문자, 숫자, 밑줄을 포함합니다.
[^문자셋]: 문자셋 안의 시작부분에 ^가 있으면 부정문자셋을 의미하고, 뒤에 나오는 문자셋을 제외한 문자가 대응됩니다.
/정규식/g: 정규식 뒤에 붙는 문자는 플래그로, 검색 옵션을 다양하게 지정할 수 있습니다. 예를 들어 i를 붙여 대소문자 구분 없는 검색을 할 수 있습니다. g를 붙여서 정규식에 해당하는 문자를 한 번만 찾고 끝나는 게 아니라 조건에 맞는 모든 문자를 찾을 수 있습니다.
/[^\w-_.]/g: \w(영문자, 숫자, 밑줄)과 -, .에 해당하지 않는 모든 문자

3단계

\.: .과 대응하는 지를 검사할 수 있습니다. 정규식에서 그냥 .은 특수문자(개행문자를 제외한 모든 문자)로 그냥 사용하면 다른 의미를 갖게 되므로 \이스케이프 문자를 붙여서 사용하였습니다. 위에서 말한 []문자셋 안에서는 이스케이프 없이 사용할 수 있었습니다.
+: +앞의 문자가 1회 이상 반복되는 형태를 말합니다.
/\.+/g: .이 1회 이상 반복되는 문자열 (., .., ...)

4단계

^: 시작을 의미합니다. ^뒤에 붙는 조건으로 시작하는지를 검사합니다.
|: 조건을 합칠 때 사용합니다. or 라고 생각하시면 됩니다.
$: 끝을 의미합니다. $앞에 붙는 조건으로 끝나는지를 검사합니다.
/^\.|\.$/g: .으로 시작하거나 .으로 끝나는지를 검사합니다.

5단계

/^$/: 시작문자도, 종료문자도 없으므로 빈 문자열을 나타냅니다. 이렇게 표현한 것은 처음 보았습니다.

6단계

slice(start?: number, end?: number): string: 시작위치(default:0)와 끝위치(default:string.length)(리턴 문자열에 포함되지 않음)으로 자른 문자열을 리턴합니다.
/\.$/: .으로 문자열이 끝나는지 검사합니다.

7단계

padEnd(targetLength:number, padString?: string): string: 목표 문자열의 길이가 될 때까지 padString으로 오른쪽에 더한 문자열을 리턴합니다. 목표 문자열의 길이보다 이미 문자열의 길이가 길면 채워넣지 않고 그냥 리턴합니다. padString의 default값은 빈 문자열입니다.

Comments