JavaScript/알고리즘

프로그래머스 A 강조하기 JS ( toLowerCase(), replace() / replace의 매개변수로 함수 / 문자클래스 [ ] , [^ ] )

hihiha2 2023. 6. 7. 13:42
반응형

프로그래머스 A 강조하기 JS 

 

문제 설명

문자열 myString이 주어집니다. myString에서 알파벳 "a"가 등장하면 전부 "A"로 변환하고, "A"가 아닌 모든 대문자 알파벳은 소문자 알파벳으로 변환하여 return 하는 solution 함수를 완성하세요.

 

 

 

✅ 내 코드

function solution(myString){
  return  myString.toLowerCase().replace(/a/g,"A")
}

처음에 보자마자 replace()가 생각났다. a를 모두 A로 바꿔야했기 때문이다.

replace를 해주기전에 먼저 모든 값을 toLowerCase()를 통해서 소문자로 바꾸었다.

그러면 모든 값이 소문자일 것이다. 이중에서 a인것만 찾아서 A로 바꾸기 위해서 replace를 쓰고 그것을 전역적으로 해주기 위해서 g로 처리하였다.

 

toLowerCase()만 먼저해줘도 엄청 쉽게 풀수있는 문제였는데, 처음에는 순서대로 a를 먼저 A로 바꿔서 하려다보니 코드가 더 복잡했었다. 생각을 바꿔서 소문자로 변환하는 과정만 앞으로 뺐을뿐인데 엄청 쉽게 풀렸다. 

해결하는 방법을 꼭 순서대로 하려는 생각을 버리려고 노력해야겠다 ㅎㅎ

 

 

 

다 풀고 다른 사람의 코드를 보다가 발견한건데, 나와 똑같은 방법인데 a를 전역적으로 검색하는지의 방법만 다르다. 

나는 /g를 통해서 여러개의 a가 오더라도 찾도록 했는데, 이 코드에서는 replace()대신 replaceAll()을 사용하였다.

const solution=s=>s.toLowerCase().replaceAll('a','A');

 

 

 

💻  다른사람 코드중에 배울 것 

function solution(myString) {
    return myString.replace(/a/g, 'A').replace(/[^A]/g, (match) => match.toLowerCase());
}

replace()를 연달아 2번 사용하여 푼 방법인데, 처음보는 것들이 있어서 공부해보았다.

앞에 replace를 통해서 a를 A로 바꾸는 것은 동일하다.

 

그 뒤의 코드에서 replace()의 두번째 매개변수함수로 사용하였다.

이게 처음보는 것이라서 이 부분에 대해서 자세히 공부했다.

 

 

 

 

💻  학습한 것

1. replace의 두번째 매개변수로 function이 오는 경우

 

✔️ replace()의 형태

var newStr = str.replace(regexp|substr, newSubstr|function)

replace()의 두번째 매개변수에는 일반 str이 올수도 있고 함수가 올수도 있다.

함수가 오는 형태만 정리해보았다.

 

 

✔️ 매개변수 function (replacement)

주어진 regexp 또는 substr에 일치하는 요소를 대체하는 데 사용될 새 하위 문자열을 생성하기 위해 호출되는 함수.

 

함수는 매개변수1의 매치가 수행된 후 호출된다.

함수의 반환값은 교체될 문자열

만약 정규식의 flag로 글로벌(g)이 오는 경우, 함수는 매칠될 때마다 계속 호출된다.

 

✔️ 함수의 매개변수

 

이제 위의 코드중 이와 관련된 부분을 다시 분석해보면,

.replace(/[^A]/g, (match) => match.toLowerCase())

두번째 매개변수로 화살표함수를 사용하였다.

화살표함수의 매개변수로 match를 사용하여 매치된 문자열만을 toLowerCase()을 통해서 소문자로 바꾼다.

 

 

 

🤔 정규식의 match()메서드와 비슷한거 같은데..?

정규식에도 match()라는 메서드가 있다. 정규식을 생성한 다음에 이 메서드를 이용하면, 일치하는 것들만 배열에 담아서 반환한다. 

 

그래서 정규식의 match()를 이용해서도 풀어보았다.

const reg = new RegExp(/[^A]/g)
function solution(myString) {
    return myString.match(reg).join("").toLowerCase().replace(/a/g,"A")
}

우선 reg라는 이름으로 정규식을 생성하였다. 그런 다음 reg와 일치하는 것들만 .match()를 통해서 검사하고 배열에 담았다. 

이걸 join을 통해서 연결해서 다 소문자로 바꾼다음에 a만 다시 A로 변경했다.

 

replace함수의 매개변수로 함수를 만들어서 풀수도 있고 이렇게 정규식의 .match메서드를 사용해서도 풀수있다.

 

 

 

 

 

2. 정규식의 특수문자중 문자클래스 [ ] , [^ ]

정규식에서는 문자클래스라는 것으로 문자와 숫자를 구분한다.

엄청 다양한 종류가 있는데 거기에서 [ ], [^] 2가지만 우선적으로 공부해보았다.

 

1️⃣ [ ]

[abcd]
[a-d]

위의 [abcd]와 [a-d]는 같은 값을 나타낸다.

 

단, 하이픈이 맨앞이나 맨뒤에 위치하는 경우에는 문자로 인식한다.

 

 

2️⃣  [^ ]

[^abc]
[^a-c]

부정된 문자클래스.

대괄호 [ ] 안에 포함되지 않은 문자를 나타낸다

 

하이픈을 이용하는것은 1️⃣과 동일하다.

 

 

더 많은 문자클래스는 아래의 사이트를 참고하면 된다.

 

 

Character classes - JavaScript | MDN

Character classes distinguish kinds of characters such as, for example, distinguishing between letters and digits.

developer.mozilla.org

 

 

🔫 assertion으로 사용되는 ^와는 의미가 다르므로 주의가 필요하다🔫

정규표현식의 특수문자로 문자클래스말고도 assertion이라는 것이 있다. 

 

assertion:

행이나 단어의 시작 · 끝을 나타내는 경계와 (앞, 뒤 읽고 조건식을 포함한) 어떤 식 으로든 매치가 가능한 것을 나타내는 다른 패턴이 포함

 

[^]와 같이 대괄호로 묶지 않은 ^는 어써션으로 문자열의 시작을 나타낸다.

/^A/는 A로 시작하는 패턴을 가리킨다.

 

 

⭐️ ⭐️ ⭐️ 

/[^A]/     'A'가 아닌 문자
/^A/      문자열의 시작이 'A'로 시작

⭐️ ⭐️ ⭐️ 

 

 

 

🙋‍♀️ 내 생각

문제자체는 어렵지 않았지만, 배운 것이 많이 있는 문제였다.

우선 보통 문제를 풀때, 문제에 나온대로 순서대로 처리하려고 했는데 발상을 전환해서 순서만 뒤바꿔도 (소문자로 먼저 만들고 A로 치환)

훨씬 쉽게 풀린다. 문제를 풀때 조금 더 다각도로 생각해보는 습관을 길러야겠다는 생각이 들었다.

 

또 replace의 매개변수로 함수를 사용할수있는지 몰랐는데 이 문제를 통해서 알게 되었다. replace는 엄청 유용하게 자주 쓸 수 있는 메서드라서 매개변수를 함수로 만드는 것을 익숙하게 하면 자주 쓸수있을것같아서 알게 돼서 좋다.

 

정규식에의 특수문자는 정말 많아서 다 한번씩 써보는데도 꽤 시간이 걸릴것같다. 그래도 이렇게 문제를 풀면서 하나씩 하나씩 사용법을 익힐수있어서 꾸준히만 계속하면 나중에는 익숙해지는 순간이 올것같다. 사실 정규식의 flag로 쓰이는 글로벌(g)도 처음 봤을땐 저게 뭐지..? 했던 것 같은데 지금은 언제그랬냐는 듯이 엄청 자연스럽게 잘 쓰고 있다 ㅎㅎ 

반응형