코딩테스트/프로그래머스 기초 트레이닝

[Javascript] 문자열 자르는 메소드 - slice() substring() substr()

dev_swH 2023. 5. 17. 15:14

문자열의 앞의 n글자, 문자열의 뒤의 n글자

문제 설명 :

(1) 문자열 my_string과 정수 n이 매개변수로 주어질 때, my_string의 앞의 n글자로 이루어진 문자열을 return 하는 solution 함수를 작성해 주세요.

(2) 문자열 my_string과 정수 n이 매개변수로 주어질 때, my_string의 뒤의 n글자로 이루어진 문자열을 return 하는 solution 함수를 작성해 주세요.

 

나는 처음에 substr() 메소드를 사용해서 문제를 풀었는데,

모질라 공식문서를 살펴보니 이 메소드가 완전히 제거된 건 아니지만 바람직하지 않은 특징을 가지고 있어서 비권장되는 메소드로 바뀌었지 뭐야.....

 

substr() 메소드란?
문자열의 특정 위치에서 시작해 특정 문자 수만큼의 문자를 반환하는 함수
사용방식 : substr(시작 위치, 길이)

 

그리하여 대체할 메소드를 외우는 김에 문자열을 자를 때 사용하는, 비슷한 메소드 2개를 아예 정리하기로 했다.

 

(1) slice()

slice() 메소드는 문자열의 일부를 추출하여 새로운 문자열로 반환하는 비파괴적 메소드다.

 

사용 방식 :
slice(시작 인덱스) ← 인덱스는 0부터 시작한다는 것을 잊지 말기~
slice(시작 인덱스, 추출 종료점 인덱스) ← 종료점 직전까지만 추출되니 헷갈리지 않게 주의!

 

공식 문서에 정리가 아주 잘 되어있다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/slice

 

String.prototype.slice() - JavaScript | MDN

slice() 메소드는 문자열의 일부를 추출하면서 새로운 문자열을 반환합니다.

developer.mozilla.org

 

(2) substring()

substring()도 slice()와 마찬가지로 문자열의 일부를 추출해서 새 문자열로 반환하는 비파괴적 메소드다.

사용 방식마저 slice()와 똑같다.

 

그렇다면 차이점은 무엇인가?

1. 인덱스 크기

substring()은 시작 인덱스가 종료 인덱스보다 큰 경우, 메소드가 두 인자를 바꾼 듯이 작동하게 된다.

그러나 slice()는 시작 인덱스가 종료 인덱스보다 큰 경우, 빈 문자열을 반환한다.

2번 음수 인식에서도 언급할 건데 slice는 무조건 추출 구간이 정방향으로 인식되어야만 하는 것 같다.

const str = 'Mozilla';

const str11 = str.substring(1, 3);
console.log(str11) ;
// Expected output: "oz"

const str22 = str.substring(3, 1);
console.log(str22) ;
// Expected output: "oz"

const str33 = str.slice(3, 1);
console.log(str33) ;
// Expected output: ""

 

2. 음수 인식

substring()은 매개변수로 음수와 NaN이 들어오면 0으로 인식한다.

const text = 'Mozilla';
text.substring(-5, 2); // => "Mo"
text.substring(-5, -2); // => "" (0, 0) 으로 인식하기 때문에 빈 문자열 반환

 

slice()도 매개변수로 NaN이 들어오면 0으로 인식하긴 한다.

그러나 slice()는 매개변수로 음수가 들어오면 매개변수 각각 역순으로 문자열 인덱스를 계산한다.

매개변수만큼 뒤에서부터 개수를 세서 문자열 인덱스를 인식하는 것이다.

(역순으로 위치 잡을 때는 평소처럼 0,1,2,3으로 세는 방식보다 공식 문서에 써있는 대로 진짜 1,2,3 이렇게 갯수로 세는 편이 시작인덱스 잡기가 훨씬 쉽다.)

 

중요한 것은 그렇게 각 매개변수의 인덱스를 잡았을 때

추출 구간이 반드시 시작점 → 종료점 이렇게 정방향 상태여야만 빈 문자열이 아니라 제대로 된 문자열 값이 반환된다.

아래 예시로 설명하자면, upon us를 추출하기 위해서는

us의 s를 시작점, upon의 u를 종료점으로 잡아 역방향으로 추출할 수는 없다는 뜻이다.

반드시 뒤에서부터 -8인 upon의 u를 시작점, -1인 us의 s를 종료점으로 잡아야만 원하는 upon us가 추출된다.

이게 생각보다 많이 헷갈려서 slice()에 음수 매개변수 2개 집어넣는 방식은 잘 사용하지 못했었다.

const str = 'The morning is upon us.';
str.slice(-3); // returns 'us.'
str.slice(-3, -1); // returns 'us'
str.slice(0, -1); // returns 'The morning is upon us'
위의 설명 예시 : str.slice(-8, -1); // returns 'upon us'

 

문제 풀이

1. 앞의 n글자

my_string.slice(0, n)

my_string.substring(0, n)

 

2. 뒤의 n글자

my_string.slice(-n)

my_string.substring(my_string.length - n)

substring()은 무조건 앞에서부터 인식하므로 길이를 구한 다음 매개변수 n을 빼는 식으로 시작점을 잡는 수밖에 없다.