[프로그래머스 / JavaScript] Lv.1 핸드폰 번호 가리기
문제
프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다. 전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해 주세요.
제한사항
- phone_number는 길이 4 이상, 20이하인 문자열입니다.
입출력 예
phone_number | return |
"01033334444" | "*******4444" |
"027778888" | "*****8888" |
내가 작성한 답안
맨 처음 작성한 답안 (02/16)
function solution(phone_number) {
let answer = ""
for(let i = 0; i < phone_number.length - 4; i++) answer += phone_number[i].replace(phone_number[i], '*');
return answer + phone_number.substring(phone_number.length - 4, phone_number.length)
}
자바스크립트 공부를 시작한 지 며칠 되지 않아 if, for문으로만 문제를 풀던 때 작성했던 코드이다! 마지막 네 자리 직전까지 for문을 돌며 하나씩 '*'로 replace 처리를 하고 마지막 네 자리를 더하는 식으로 값을 완성했다.
다시 풀어본 답안 (04/07)
function solution(phone_number) {
const str = phone_number.slice(0, -4);
return phone_number.replace(str, '*'.repeat(str.length));
}
항해99 알고리즘 주차에 다시 풀어본 코드! 마스킹 처리할 부분은 들어올 phone_number 길이마다 다르므로 마지막 네 자리를 제외한 모든 값을 변수에 담는다. 그 후 해당 부분의 길이만큼 repeat하여 replace하는 방식으로 해결했다. 확실히 맨 처음 공부할 때와 지금 다시 풀어본 코드를 비교보니 조금 성장했다는 게 가시적으로 보였다.
다른 사람들이 작성한 답안
이 문제는 사람들마다 사용한 메서드가 다 달라 답안을 보는 재미가 있는 문제였다.
1. 정규표현식
function solution(phone_number) {
return phone_number.replace(/\d(?=\d{4})/g, "*");
}
코드에 사용된 정규표현식 알아보기
\d | 숫자만 사용되었는지 검증한다. |
(?=) | ?= 뒤에 오는 문자로 찾되 선택에서는 제외한다. |
{n} | {n}개인지 검증한다. |
/g | 문자열 내 모든 패턴을 검색한다. |
해당 코드가 왜 맨 첫 글자부터 맨 뒤의 4자리를 제외한 값들을 선택했는지 궁금해 찾아보았다.
예제 값을 0123456789로 두고 정규표현식 \d를 작성하면 \d는 숫자인지를 검증하는 표현식이므로 모든 숫자가 매칭된다.
뒤에 오는 문자로 찾되 선택에서는 제외하라는 의미의 ?=를 걸어주고 숫자인지 판별하는 \d를 붙여준다. 이렇게 할 경우 0123456789 중에서 9를 제외한 0~8까지의 값이 매칭된다. 왜 마지막 숫자 9는 빼고 매칭이 될까? 찾아보니 A(?=B)는 look foward라고 하는데 A를 찾되 B가 따라붙는 경우에 대해서만 A에 대해 매치된다고 한다.
\d(?=\d{1})을 했을 경우는 위의 \d(?=\d)와 동일하게 9는 제외하고 매칭되었고, 문제풀이와 같이 {4}로 네 자리를 선택했을 경우 맨 뒤부터 네 자리를 제외하고 매칭되었다.
원리가 이해가지 않아 계속 구글링을 했는데, 어색한 번역본이 많아 잘 이해가 가지 않았다. 여기서 더 파고들면 다른 것에 집중할 수 없을 것 같아 접어두고 (?=)로 매칭했을 경우 맨 뒤부터 제외한다는 것을 외워두기로 했다.
2. fill 메서드
const solution = n => [...n].fill("*",0,n.length-4).join("")
전달받은 phone_number를 n으로 받고, 스프레드 연산자를 이용해 해당 값을 넣은 배열로 만든다. (['0', '1', '0', '1', '2', '3', '4', '5', '6', '7', '8']) 그 후 fill을 이용해 동일한 문자를 채우는데 0번째 인덱스부터 length - 4까지의 범위로 채운다. 채우는 값은 '*'로 하고, 해당 값은 배열인데 return해야 하는 값은 문자열이므로 join('')을 이용해 배열을 문자열로 만들어준다.
3. for문과 삼항연산자
function solution(phone_number) {
var result = "";
for(var i=0; i<phone_number.length; i++){
result += i < phone_number.length-4 ? "*":phone_number.charAt(i);
}
return result;
}
0번째 인덱스부터 for문을 돌며 length - 4가 아닐 경우 '*', 맞을 경우 해당 값으로 새로운 값을 담는 result 변수에 채워준다.
[참고 자료]
https://school.programmers.co.kr/learn/courses/30/lessons/12948
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
📚 JavaScript 정규 표현식 문법 총정리 + 응용 예제
정규 표현식(Regular Expression) 정규식(Regular Expression)은 문자열에서 특정 내용을 찾거나 대체 또는 발췌하는데 사용된다. 대표적으로 입력칸에 전화번호나 이메일을 입력하라고 했을때 옳지 않은
inpa.tistory.com
정규식 Lookahead와 Lookbehaind
정규식은 일정한 패턴을 이용하여 입력된 문자열 정보가 조건에 일치하는지 확인하거나 특정 조건에 맞추어 치환 할 때 주로 사용된다. 물론 정규식이 아니라도 프로그래밍과 같은 다양한 방식
mc500.tistory.com