오늘 뭐했냐/기억하면 좋을 문제들

정규 표현식 연계

스스로에게 2023. 6. 21. 18:59

프로그래머스 "신규 아이디 추천" 조건에 맞춰 문자열을 제거하거나 바꾸는 문제였다 

 

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

 

function solution(new_id) {
    let one = new_id.toLowerCase() // 1. 소문자 전환
    let two = one.match(/[\w,.,' ',-]/g) // 2. 정해진 문자만 찾기
    let three = []

    for (i = 0; i < two.length; i++) {
        if (two[i - 1] === two[i] && two[i] === '.') {
            continue
        }
        if (two[i] === ' ') {// 5. 빈문자열 a로 대체
            two[i] = 'a'
        }
        three.push(two[i]) // 3. 연속된 '.' 제거
    }

    if (three[0] === '.') three.splice(0, 1)
    if (three[three.length - 1] === '.') three.splice(three.length - 1, 1) // 4. 앞 뒤 '.' 제거

    three.splice(15) // 6. 15자 맞추기
    if (three.length === 0) { three.push('a') }
    if (three[three.length - 1] === '.') three.splice(three.length - 1, 1) // 6-2 다시 앞 뒤 '.' 제거

    while (three.length < 3) {
        three.push(three[three.length - 1])

    }
    return three.join('');
}

하나씩 조건을 추가하며 잘 실행되나 싶었는데 몇 개를 통과하지 못해서 80점이 나왔다

 

사실 다른 사람들의 풀이를 보고 느꼈지만 이 문제는 정규표현식을 연계해서 풀어야하는 문제인 것 같다. 물론 다른 풀이도 있지만 가장 문제강 원하는 답은 정규 표현식 같았다 

 

function solution(new_id) {
    const answer = new_id
      .toLowerCase() // 1
      .replace(/[^\w-_.]/g, "") // 2 // 조건에 맞는 문자열을 제외하고 모두 제거 
      .replace(/\.+/g, ".") // 3    // 하나 이상은 연속된 거 모두 '.'으로 변경
      .replace(/^\.|\.$/g, "") // 4  // ^\.특정 문자열로 시작 \.$ 특정 문자열로 끝남 | =>  or  그냥 .을 쓰면 이것도 패턴 중 하나로 인식됨
      .replace(/^$/, "a") // 5  // ^(시작)과 &(끝) 사이에 아무것도 없는 빈문자열이면 "a"로 대체됨
      .slice(0, 15)
      .replace(/\.$/, ""); // 6 // 다시 끝에 "." 제거 
    const len = answer.length;
    return len > 2 ? answer : answer + answer.charAt(len - 1).repeat(3 - len);
  }

 

먼저 내가 문제를 잘못 생각했었다. 조건에 맞춰서 문자를 날리는 게 더 좋아보이고 무엇보다 정규표현식을 단순히 특정 문자를  찾는데만 사용했기에 .match()만을 사용했었는데 이렇게 replace로 문자를 지우거나 혹은 처음과 끝을 지정하는 등의 다른 사용법도 있다는 것을 배웠다

'오늘 뭐했냐 > 기억하면 좋을 문제들' 카테고리의 다른 글

스택을 사용하는 문제  (0) 2023.06.25
생각을 넓히자  (0) 2023.06.23
Map활용해보기  (0) 2023.06.17
객체 구조를 활용한 배열 빼기  (0) 2023.06.16
Set 자료구조로 문자열 전달  (0) 2023.06.15