티스토리 뷰

"현" 이란 문자를 "소"라는 문자로 바꾸고 싶다.

원하는 결과값(result) 는 "소수철수민수" 이다

하지만 아래 코드를 실행했을 때 "현수철수민수"로 결과가 나온다.

const hyeon = "현수"
const chulsu = "철수"
const minsu = "민수"

const threeMan = hyeon + chulsu + minsu;


function changeWord(longstring, a, b){
    for(let i = 0; i < longstring.length; i++){
        if(longstring[i] === a){
            longstring[i] = b;
        }
    }
    return longstring;
}

const result = changeWord(threeMan, "현", "소");
console.log(result) // 현수철수민수

 

why?

 

GPT씨

JavaScript에서 문자열은 불변(immutable)하다는 점입니다.

따라서 문자열을 한 번 생성하면 해당 문자열의 내용을 직접 수정할 수 없습니다.

따라서 changeWord 함수 내에서 combineWord[i] = b와 같은 방식으로 문자열을 변경할 수 없습니다.

해결 방법으로는 changeWord 함수가 새로운 문자열을 반환하도록 수정하는 것입니다.

새로운 문자열을 반환하면서 원하는 문자를 바꾸는 것이 좋습니다.

 

네. 그렇습니다.. 

새로운 문자열을 반환하기 위한 방법은 뭐가 있을까?

  1.  String.prototype.split() 메서드 사용
  2.  String.prototype.replace() 메서드 사용

 

1번 코드 : split 메서드 사용, 이 방식에 익숙해져야한다.

// 1번 방법 : 문자열을 배열로 변환하고, 변경된 배열의 각 원소를 검사하고 수정한 후에 Array.prototype.join() 메서드를 사용하여 다시 문자열로 결합합니다.
function changeWord(combineWord, a, b){ // 순수함수
    const characters = combineWord.split('')
    for (let i =0; i < characters.length; i++){
        if(characters[i] === a){
          characters[i] = b
        }
    }
    return characters.join('') // split으로 나눈 단어들을 다시 문자열로 결합해줘야한다.
}

const result_1 = changeWord(threeMan, "현", "소")
console.log(result_1) // 소수철수민수

 

2번 코드 (1) : replace 안에 정규표현식 사용하지 않음, 첫번째로 발견된 a값만 b로 대체된다.

// 2번 방법 : replace(a,b) 
// 문제점 : 정규표현식을 사용하지 않으면 첫번째로 발견한 a만 b로 대체된다.
function replaceWord(combineWord, a, b){
   return combineWord.replace(a, b) 
}
const result_2 = replaceWord(threeMan, "현", "소")
console.log(result_2) // 소수철수민수

 

2번 코드 (2) : replace 안에 정규표현식 사용, new 생성자를 통해 RegExp 객체생성

// 3번방법 : 'RegExp' 객체를 사용, new 생성자를 통해 정규식을 생성
function replaceWordUseRegExp(combineWord, a, b){
  return combineWord.replace(new RegExp(a, 'g'), b)
}

const result_3 = replaceWordUseRegExp(threeMan, "현", "소")
console.log(result_3) // 소수철수민수

 

2번 코드(3) : replace 안에 정규식 리터럴 사용, 원하는 결과값이 나오지 않음.

// 4번 방법 : 정규식 리터럴 사용, 이건 안됨
// 문제점 : 정규식 리터럴은 정적인 패턴을 가지며 변수나 다른 동적인 값으로 변경할 수 없습니다.
// 정규식 리터럴은 코드가 파싱되는 시점에 정규식이 생성되기 때문에 변수를 사용하여 동적인 패턴을 생성할 수 없습니다.
function replaceLiteralRegExp(combineWord, a, b){
  return combineWord.replace(/a/g, b)
}
const result_4 = replaceLiteralRegExp(threeMan, "현", "소")
console.log(result_4) // 현수철수민수

 

why? 

 

GPT씨

정규식 리터럴은 코드가 파싱되는 시점에 정규식이 생성됩니다.

이는 코드 실행 전에 정규식이 이미 컴파일되어 있음을 의미합니다.

따라서 정규식 리터럴 내에서 변수를 사용하여 동적인 패턴을 생성하려고 하면,

변수에 값이 할당되기 전에 이미 정규식이 생성되어 버립니다.

 

예를 들어, 다음과 같이 코드가 작성되었다고 가정해 봅시다:

const pattern = 'a';
const regexLiteral = /pattern/g;

 

여기서 /pattern/g는 정규식 리터럴입니다.

그러나 이렇게 하면 실제로는 문자열 'pattern'이라는 정규식 패턴을 생성하게 됩니다.

즉, 변수 pattern에 할당된 값 'a'를 기반으로 정규식을 생성하지 않고,

단순히 문자열 'pattern'을 정규식 패턴으로 사용합니다.

 

따라서 변수를 사용하여 동적인 패턴을 생성하려면 RegExp 객체를 사용하여 정규식을 생성해야 합니다.

이를 통해 코드가 실행되는 동안에 변수의 값을 기반으로 정규식을 생성할 수 있습니다.

 

변수로 할당된 값에 대해 정규표현식을 사용하려고 할 땐 RexExp객체를 사용하여 정규식을 생성하자