[프로그래머스] 핸드폰 번호 가리기 _JavaScript

ne_ol·2022년 1월 15일
0
post-thumbnail

문제 설명

프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다.
전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.

제한 조건

  • s는 길이 4 이상, 20이하인 문자열입니다.

예시

phone_numberreturn
"01033334444""*******4444"
"027778888""*****8888"

기본 solution 코드

function solution(phone_number) {
    var answer = '';
    return answer;
}

문제 풀이

//첫 번째 풀이
function solution(phone_number) {
    var answer = ""
    var back_number = phone_number.substr(-4, 4); //phone_number의 뒤에서 4번 째 index부터 4개를 빼라
    var front_number = phone_number.substring(0, phone_number.length-4); 
    //phone_number의 0번 째 index부터 뒤에서 4번 째 index까지 빼라
    front_number.replace(/[0-9]/g,'*'); //검색범위를 전역으로 확장하고 0~9사이의 문자를 찾아서 '*'로 대체해라
    answer = front_number.replace(/[0-9]/g,'*') + back_number;
    return answer;
}

//한 줄로 만들어보겠다고 만들어본 풀이
function solution(phone_number) {
    return phone_number.slice(0, -4).replace(/[0-9]/g,'*') + phone_number.slice(-4); 
    //phone_number의 0번 째 index부터 뒤에서 4번 째 index까지 자르고 '*'로 대치한 것 + phone_number의 뒤에서 4번 째 index부터 자른 것
}

풀이 설명

문제를 보자마자 가운데 글자 가져오기 에서 다른 풀이에 나왔던 함수 .substr() 가 생각났다. 일단 이 function으로 뒤 네 자리를 빼낼 수 있었다. 하지만 문제는 length가 정해져있지 않은 앞자리였다. 따라서 length 가 아닌 지정 index까지 빼낼 수 있는 .substring을 사용하여 앞자리를 빼냈다.
대체는 .replace()가 바로 떠올랐지만 어떻게 쓰는지 몰라 헤매다가 '정규식으로 특정 문자 제거' 를 참고하여 해결할 수 있었다.

다른 사람들의 ganzi 나는 코드들을 고작 하루 봤다고 나 또한 한 줄로 만들고 싶어져서 하나의 함수를 써야겠다고 생각했다. .substr()와 .substring()을 합쳐놓은 것 같은 .slice()를 사용하여 해결했고, 한 줄로 만들기 위해 .replace()를 바로 붙혀서 만들어버렸다.

사용 함수

  • .substr(start, length): 가운데 글자 가져오기 참고
  • .substring(indexStart[, indexEnd]): string 객체의 시작 인덱스로 부터 종료 인덱스 전 까지 문자열의 부분 문자열을 반환
  • .slice([begin[, end]]): 어떤 배열의 begin부터 end까지(end 미포함 시)에 대한 얕은 복사본을 새로운 배열 객체로 반환
  • .replace(regexp|substr, newSubstr|function)
    • 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환
      • regex (pattern): 정규식(RegExp) 객체 또는 리터럴. 일치하는 항목은 newSubStr 또는 지정된 함수(function)가 반환 한 값으로 대체
      • substr (pattern): newSubStr로 대체 될 String. 정규식이 아닌 글자 그대로의 문자열로 처리. 오직 첫 번째 일치되는 문자열만이 교체
      • newSubStr (replacement): 첫번째 파라미터를 대신할 문자열(String)
      • function (replacement): 주어진 regexp 또는 substr에 일치하는 요소를 대체하는 데 사용될 새 하위 문자열을 생성하기 위해 호출되는 함수
  • 정규식 (RexExp)
    • g: 전역 검색
    • [0-9]: 숫자 문자

(출처: https://developer.mozilla.org/ko/)


다른 풀이

//첫 번째 풀이
function solution(phone_number) {
  return phone_number.replace(/\d(?=\d{4})/g, "*");
}

//두 번째 풀이
function solution(phone_number){
  var result = "*".repeat(phone_number.length - 4) + phone_number.slice(-4);
  return result;
}

다른 풀이 설명

  1. 사용된 함수
  • .repeat(count): 직사각형 별찍기 참고
  • 정규 표현식 (정규식)
    • \d: 숫자 문자에 대응. [0-9]와 동일.
    • x(?=y): 오직 'y'가 뒤따라오는 'x'에만 대응 (lookahead)

(출처: https://developer.mozilla.org/ko/)

  1. 풀이
  • 두 번째 풀이는 한 번 사용한 적이 있었던 .repeat()함수만 생각했으면 충분히 쓸 수 있었을 거라 생각된다.
  • 첫 번째 풀이에서 정규식 표현들은 이해가 됐는데, \d(?=\d{4})가 정확히 이해가 되지 않았다.
    • /\d{4}/ 만 돌릴 경우
    • /\d{4}/g 음?
    • /\d{4}/g가 뭔지 몰라서 phone_number 11자리를 12자리로 바꿔서 돌려봤다.
  • 결론: \d{4}는 4자리 숫자를 가리킨다. 따라서 첫 번째 사진에서 \d{4}는 0101를 *로 대체한 것이다. 두 번째 사진에서는 \d{4}를 전역으로 검색해서 0101과 2345 이 두 개를 *로 대체시킨 것이다. 마찬가지로 세 번째 사진에서는 0101, 2345, 6789 를 *로 대체시켜 3개의 *를 돌려준 것이다.
  • d(?=\d{4}) 는 lookadhead로 인해 d{4} (네 자리 숫자) 가 뒤따라오는 d (숫자), 결국 전체 숫자에서 뒤 네자리를 뺀 앞 자리들의 숫자를 의미하기 때문에 원하는 결과를 얻은 것이다.
  1. 정규식 미쳤다.
profile
개발되는 중입니다.

0개의 댓글