프로그래머스 Level 1 에 있는 문제이다.

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이 될 때까지 반복해서 끝에 붙입니다.


function solution(new_id) {
// 아이디의 길이는 3자 이상 15자 이하
// 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용 가능
// 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없다.
var answer = '';
var reg = /[._-]|[\w]|[\d]/g; // 알파벳 소문자, 숫자, 빼기, 밑줄, 마침표만 필터하는 정규식
var dotReg = /\.{2}/g; // ..을 검출하는 정규식
// 1단계 : 전체 소문자 만들기
var id = new_id.toLowerCase();
// 2단계 : 알파벳 소문자, 숫자, 빼기, 밑줄을 제외시키고 배열을 문자열로 만들기
id = id.match(reg).join("");
// 3단계 : .. < 없애기
while(true){
id = id.replace(dotReg, ".");
if(id.search(dotReg) === -1){
break;
}
}
// 4단계 : 문자열의 첫번째가 마침표로 끝날경우, 마침표 제거
if(id[0] === ".") {
id = id.substring(1);
} // 끝이 마침표로 끝날경우, 마침표 제거
if(id[id.length - 1] === ".") {
id = id.substring(0, id.length - 1);
}
// 5단계 : 문자열이 비어있으면 a로 치환하기
if(id === ""){
id = "a";
}
// 6단계 : id의 길이가 16자 이상이면, 15자 이후로 자르고,
if(id.length >= 16) {
id = id.substring(0, 15);
if(id.endsWith('.')) { // 만약 끝에 있는 문자열이 마침표이면, 마침표 제거
id = id.substring(0, id.length - 1);
}
}
// 7단계 : 문자열의 길이가 2이하일 경우 마지막 문자를 길이가 3이 될때까지 반복
if(id.length <= 2) {
for(var i = id.length; i < 3; i++ ){
id += id.charAt(id.length - 1);
}
}
answer = id;
return answer;
}

나의 풀이같은 경우는 되게 하드코딩으로 풀었다.
문제에 제시 된 단계를 보고, 그걸 그대로 if문과 반복문을 써서 풀었다.
정규식도 잘 몰라서 푸는데 꽤 오래걸린것같다.
보고 감탄한 다른사람의 풀이이다.
정규식과 replace를 이용해서 이렇게 심플하게 풀 수도 있구나 느꼈다. 한수 배웠다..
const solution = (new_id) => {
const id = new_id
.toLowerCase() // 1
.replace(/[^\w\d-_.]/g, '') // 2
.replace(/\.{2,}/g, '.') // 3
.replace(/^\.|\.$/g, '') // 4
.padEnd(1, 'a') // 5
.slice(0, 15) // 6
.replace(/^\.|\.$/g, '')
return id.padEnd(3, id[id.length-1]) // 7
}
우선 이 코드를 보면 메서드 체이닝과 replace를 이용해서 간단하게 풀었다.
우선 이 코드를 해석하려면 각 정규식이 어떤 역할을 하는지 해석이 필요했다.
먼저 주석에 번호를 달아놓았으니, 번호대로 차례대로 해석해보려고한다.
여기까지 다른 사람이 작성한 코드를 해석해봤다.
해석하면서 정규식 공부도 조금 된 것 같다 ㅋㅋㅋㅋㅋ
나는 이 문제를 푸는데 체감상 거의 한 시간 ~ 두 시간 정도 걸린것같다.
그래도 다른 사람의 코드를 먼저 보지않고, 자바스크립트 docs 를 뒤적거리면서 풀었다는게 되게 뿌듯했다.
그리고 이 문제를 풀면서 정규식의 형태?? 에서도 천천히 둘러볼 수 있어서 좋았다.
정규식은 시간 날 떄 틈틈히 활용하는 연습을 해봐야겠다.

https://regex101.com/ < 정규식 연습하는 사이트!