Modern Javascript 문자열

[Modern Javascript] 문자열


본 내용은 모던 자바스크립트 문자열을 보고 공부, 정리한 내용입니다.

자바스크립트에는 문자 하나만 저장할 수 있는 자료형이 없다. 모든 문자는 문자열의 형태로 저장된다.

자바스크립트에서 문자열은 페이지 인코딩 방식과 상관없이 UTF-16 형식을 따른다.

문자열 표현 방식 - 따옴표

문자열을 표현할 때 큰 따옴표, 작은 따옴표, 백틱 3가지를 이용할 수 있다.
백틱을 이용하면 다채로운 문자열 표현이 가능하다.

  1. 템플릿 리터럴
    1
    2
    3
    4
     function sum(a, b) {
       return a + b;
     }
     alert(`1 + 2 = ${sum(1, 2)}.`); // 1 + 2 = 3.
    
  2. 여러 줄 표현
    ```jsx let guestList = `` `손님:
    • John
    • Pete
    • Mary `; alert(guestList); // 손님 리스트를 여러 줄에 걸쳐 작성함 `

    따옴표로 여러 줄을 표현하기 위해서는 ‘\n’을 사용해야 한다. 백틱처럼 사용하면 에러가 난다.

    1
    2
    3
    4
     alert("손님:
     * John"); // 에러
    
     alert("손님: \n * John"); // 정상
    

특수 기호

자바스크립트에서 사용되는 특수 기호는 다른 언어와 거의 동일하다.
기본적으로 이스케이프 문자 ‘'(역슬래쉬) 로 시작한다.
독특한 특수 기호로는 ‘\x’, ‘\u’ 정도가 있다.

  • \x
    \xXX 와 같이 사용되며, 16진수 두 자리를 유니코드로 인식하여 이를 문자로 변환한 값을 의미한다.

  • \u
    \uXXXX 혹은 \u{X..XX} 와 같이 사용된다.
    \uXXXX는 UTF-16 인코딩 규칙을 사용하는 16진수 코드 XXXX로 표현한 유니코드 기호이다.
    \u{X…XX}에서 X는 1개 이상 6개 이하가 존재할 수 있으며, UTF-32로 표현한 유니코드 기호이다.

1
2
3
4
5
// 예시
alert( "\x7A" ); // z
alert( "\u00A9" ); // ©
alert( "\u{20331}" ); // 佫, 중국어(긴 유니코드)
alert( "\u{1F60D}" ); // 😍, 웃는 얼굴 기호(긴 유니코드)

문자열 내에서 작은 따옴표나 큰 따옴표, 역슬래쉬를 출력하고 싶으면 해당 문자 앞에 역슬래쉬를 붙여주거나, 문자열 전체를 백틱을 이용하여 출력하면 된다.


문자열의 길이

문자열 길이는 length 속성을 이용하여 구할 수 있다.

1
2
console.log("my\x7A\n"); // myz
console.log("my\x7A".length); // 4

눈여겨보아야 할 점은, 위 문자열에서 ‘\n’ 또한 문자열 내에서 자리를 차지하는 특수 문자이므로 길이가 3이 아닌 4가 된다.

  • 주의
    length는 메서드 호출이 아니라 속성 접근이라는 것을 기억하자. .length()는 틀린 호출 표현이다.

특정 글자에 접근

특정 글자에 접근할 땐 대괄호 표현식, 혹은 내장함수 charAt을 사용할 수 있다.

접근할 수 없는 인덱스에 접근을 시도하면?
대괄호 표현식을 사용했으면 undefined가 호출된다.
내장함수 charAt을 사용했으면 빈 문자열이 출력된다.

문자열 순회

문자열을 순회할 때는 for..of 문을 사용하면 편하다.
습관적으로 for..in 문을 사용하여 문자열을 순회할 때가 있는데, for..in은 key 순회이고 for..of는 value순회라는 것을 차이를 꼭 기억하자.

1
2
3
4
5
6
7
8
9
10
11
const str = "hello";

for(let char in str) {
    console.log(char);
}
for(let char of str) {
    console.log(char);
}
// 결과. 편의상 출력 결과의 개행문자는 생략하여 적었다.
01234
hello

문자열의 불변성

자바스크립트에서 문자열은 변할 수 없다.
특정 문자열에 문자를 추가하거나 삭제하고 싶다면 문자열을 새로 만들어 그곳에 저장해야 한다.

1
2
3
let hi_1 = "hello";
hi_1 = hi_1 + " matthew"; // 기존 문자열을 변경하는 것이 아닌, 문자열을 새로 할당.
console.log(hi_1);

부분 문자열 찾기

부문 문자열을 찾는 메서드는 3가지가 존재한다.

str.indexOf(substr, [pos])

pos 부터 시작해서 substr을 찾는 메서드이다.
pos는 선택적인 인자이며, substr을 찾았을 경우 해당 위치의 시작 인덱스를 반환하며, 찾지 못했다면 -1을 반환한다.
이 메서드를 사용하여 전체 문자열을 순회하고 싶다면 아래와 같은 코드로 가능하다.

1
2
3
4
5
6
7
let str = "As sly as a fox, as strong as an ox";
let target = "as";

let pos = -1;
while ((pos = str.indexOf(target, pos + 1)) != -1) {
  alert( `위치: ${pos}` );
}
  • 주의
    아래와 같이 str.indexOf를 사용하면 의도한 결과가 나오지 않는다.

    1
    2
    3
    4
    5
      let str = "Widget with id";
    
      if (str.indexOf("Widget")) {
          alert("찾았다!"); // 동작하지 않습니다.
      }
    

    “Widget” 문자열이 인덱스 0 에 있기 때문에, if문은 이 식을 false로 인식한다.
    의도한 결과를 얻기 위해선 -1과 비교해주어야 한다.

    혹은 NOT 비트연산자를 사용하는 방법도 가능하다.
    NOT 비트연산자는 피연산자가 n일 때 ~n → -(n+1) 와 같이 변환한다.
    if문은 0을 false, 나머지 숫자를 true로 인식하고, ~(-1) = 0 이므로 아래와 같이 조건식을 쓸 수도 있다.

    1
    2
    3
    4
    5
      let str = "Widget with id";
    
      if (~str.indexOf("Widget")) { // "widget"을 찾지 못했을 경우 조건식이 ~(-1) = 0이 된다.
          alert("찾았다!"); // 의도한 대로 동작합니다.
      }
    

includes, startsWith, endsWith

이 세 가지 메서드는 true, false 를 리턴하는 메서드이다. 포함 여부만 알고 싶을 때 유용하다.
includes 메서드는 indexOf 와 마찬가지로 두 번째 인자가 선택적이며, 탐색 시작 위치를 지정해 줄 수 있다.
startsWith, endsWith 메서드는 문자열 하나를 인자로 받는다.


부분 문자열 추출

문자열을 추출할 수 있는 메서드는에는 substring, substr, slice 가 있다.

str.slice(start [,end)

start 부터 end 까지의 문자열을 추출한다. end가 주어지지 않을 경우 문자열의 마지막까지 추출한다.
start, end가 음수가 될 수 있다. 음수로 쓰였을 시 마지막 인덱스부터 카운트한 인덱스로 해석한다.

1
2
3
4
let str = "stringify";

// 끝에서 4번째부터 시작해 끝에서 1번째 위치까지
alert( str.slice(-4, -1) ); // gif

start보다 end가 작을 경우 빈 문자열이 출력된다.

str.substring(start [, end])

slice와 비교했을 때, 두 가지 차이점이 있다.

  • start, end가 음수가 될 수 없다.
  • start가 end보다 클 수 있다. 이 때는 end ~ start 범위의 문자열을 추출한다.

str.substr(start [, length])

start 부터 length 만큼의 문자열을 추출한다는 점에서 위 두 메서드와 차이가 있다.
start는 음수가 될 수 있으며, length가 주어지지 않을 경우 문자열 마지막까지 추출한다.


문자열 비교

문자열을 대소비교할 땐 앞 문자부터 문자의 유니코드값을 비교한다.
발음 기호가 붙은 알파벳은 기본 알파벳과 유니코드가 다르다는 것을 기억하자.

str.fromCodePoint메서드를 이용하여 유니코드를 문자로 변환할 수 있다.
str.codePointAt 메서드를 이용하여 문자열의 특정 문자의 유니코드 값을 알아낼 수 있다.
발음 기호가 붙은 문자는 문자 간 조합으로 만들거나, 지정된 유니코드값으로 만들 수 있다.

1
2
3
alert( 'S\u0307' ); // Ṡ
alert( 'S\u0307\u0323' ); // Ṩ
alert( 'S\u0323\u0307' ); // Ṩ

위의 두 번째 문자와 세 번째 문자를 비교한다면 false가 출력된다. 엄밀히 얘기하면 유니코드 배합 순서가 다르므로 서로 다른 유니코드이기 때문이다.
이와 같은 상황을 방지하려면 정규화 과정이 필요한데, str.normalize() 메서드가 이 역할을 해준다.
단, 유니코드에 해당 조합을 갖는 특수한 문자가 정의되어 있어야 str.normalize()에 의해 정규화 됨을 기억하자.

0%