[JS] 문자열의 위치 찾기 & 문자열 추출하기

MJ·2022년 9월 21일
1

Java Script

목록 보기
41/57
post-thumbnail

문자열의 길이

.length 프로퍼티엔 문자열의 길이가 저장됩니다.

alert(`My\n`.length);	// 3, \n 특수 기호도 문자열로 취급합니다. 

length 는 함수가 아닌 프로퍼티 입니다. length() 이렇게 사용할 수 없다.


특정 글자에 접근하기

문자열 내 특정 위치인 pos에 있는 글자에 접근하려면 [pos] 같이 대괄호를 이용하거나
str.charAt(pos)라는 메서드를 호출하면 됩니다. 위치는 [0]부터 시작 됩니다.

let str =`Hello`;

// 첫 번째 문자 출력
alert(str[0]);			// H
alert(str.charAt(0));	// H

// 네 번째 문자 출력
alert(str[str.length -1]);	// o, length는 문자열의 길이를 나타 낸다.
// 5-1 = str[4]o 출력 

[] 대괄호와 charAt() 함수의 차이점

charAt() 함수보다는 [] 대괄호를 사용해서 문자열에 접근하는 방식을 권장합니다.
두 방식의 차이점은, 존재하지 않는 문자열을 반환할 때 나타납니다.

[] 대괄호는 접근하는 위치에 문자열이 없다면 undefined를 반환.
charAt() 메서드는 접근하는 위치에 문자열이 없다면 ' '빈 문자열을 반환.

let str='Hello';

alert( str[5] );		// undefined
alert( str.charAt(5) );	// ' '

for of 사용

for 문에서 of를 사용하면 문자열을 구성하는 글자를 대상으로 반복문을 수행합니다.

for(let char of "Hello"){
 alert(char);	// 순차적으로 H,e,l,l,o 가 출력 됩니다. 
}



문자열의 불변성

문자열은 수정할 수 없습니다. 문자열의 중간 글자를 바꾸려고 하면 오류가 발생합니다.

let str = 'Hi';

str[0] = 'h';		// 오류 발생, 변경되지 않습니다.
alert( str[0] );	

기존에 문자열에서 수정하고 싶다면, 새로운 문자열을 만들면 됩니다.

let str = 'Hi';

str = 'h' + str[1];	// h와 str[1] = i을 병합합니다.
alert(str);			// hi;



대 소문자 변경하기

toLowerCase() 메서드는 대문자를 소문자로 변경
toUpperCase() 메서드는 소문자를 대문자로 변경

인수 값을 설정해주면 특정 문자열의 글자만 변경할 수 있습니다.

alert( `Interface`.toUpperCase() );	// INTERFACE
alert( `Interface`.toLowerCase() );	// interface

alert( `Interface`[0].toLowerCase() ); // i, 문자열에서 [0]번쨰에 해당하는 글자만 변경(I)



str.indexOf(substr, position)

str.indexOf(substr, pos) 메서드는 str 문자열에서 찾고자 하는 일부분의 위치를
찾아줄 수 있습니다.

  • substr은 찾고자 하는 문자열
  • postion은 문자열 탐색의 시작 위치

문자열을 찾게 되면 위치 값을 반환하고, 찾지 못하면 -1을 반환합니다.


str.indexOf(substr)

indexOf 메서드에서 첫 번째 인수만 사용 할 경우, 탐색의 시작 위치는 0이 됩니다.

// 첫 번째 인수만 사용 할 경우 시작 위치는 문자열의 0이 됩니다.

let str = 'Widget with id';

alert( str.indexOf('Widget') );	// 0, Widget은 0의 위치에 존재.
alert( str.indexOf('widget') );	// -1, 대 소문자를 구분하기에 찾지 못함
alert( str.indexOf('id') );		// 1, id는 str에서 [1]번째 위치에 존재한다. (W[0] i[1])

str.indexOf(substr, position)

두 번째 인수 pos는 선택적으로 사용할 수 있습니다.
이를 사용하면 검색이 pos 위치에서 부터 시작됩니다.

let str = 'Widget with id';

alert( str.indexOf('id' , 2) );	// 12, str[2]번째 위치에서 부터 id를 찾습니다.

반복되는 문자열 찾기

전체 문자열에서 중복되는 문자열의 위치를 찾고 싶다면, for문을 사용할 수 있습니다.
반복문 내부에서 indexOf 메서드를 사용하면, 전체 문자열에서 중복되는 문자열 부분을
찾아낼 수 있습니다.

let str = 'As sly as a fox, as strong as an ox';
let target = 'as';	// 위 반복문에서 as 반복문을 찾기

let pos = 0;
while(true) {
 let foundPos = str.indexOf(target, pos);
 if(foundpos == -1) break;
  
 alert(`현재 target의 위치는 '[${foundpos}]' 번째 입니다.`);
 pos = foundpos + 1;	// as를 찾게 되면, 다음 위치에서 다시 찾습니다.
}


// 위 코드를 간소화 시키면 아래처럼 됩니다. ↓


let str = 'As sly as a fox, as strong as an ox';
let target = 'as';	// 위 반복문에서 as 반복문을 찾기

let pos = -1;

while( (pos = str.indexOf(target, pos + 1)) != -1 ) { 
    alert(`현재 target의 위치는 [${pos}] 번째 입니다.`);
}


/* */
1) 조건문이 참인 경우 반복 수행 ( pos가 -1이 아닌 경우 )
2) 반복문을 수행할 때 마다 pos의 값을 증가시켜서, 다음 위치에서 탐색할 수 있게 설정
3) 다음 위치 이후에서 'as' 문자열을 찾을 수 없다면 -1 반환

🔔 str.lastIndexOf()

lastIndexOf(subter, position) 함수는 IndexOf() 함수와 같이 문자열 전체에서
부분 문자열을 찾아줍니다. 시작 위치pos는 문자열의 끝 부분이 됩니다.'


if 조건문과 indexOf

indexOf 함수를 if 조건문에서 사용할 때 주의점이 있습니다. 찾으려는 일부분의 문자열이
str[0]번째에 위치하면, 0의 값을 반환하므로 if문이 실행되지 않습니다.

let str = "Hello World";

if( str.indexOf('Hello') ) {	// 반환 값이 0(false)가 되어 조건문이 실행되지 않음
  alert('문자열 찾기 완료');
}


// ↓ 위 같은 상황을 배제하기 위해서 -1과 비교하면 됩니다.


let str = "Hello World";

if( str.indexOf('Hello') != -1 ) {	// 0은 1과 같지 않으므로 표현식은 참
 alert('문자열 찾기 완료'); 
}



비트 NOT 연산자

현재는 사용하지 않는 연산자 중 하나이지만, 오래된 스크립트를 읽기 위해서 알아둡시다.
비트 NOT 연산자는 피연산자를 32비트 정수로 변환하고 모든 비트를 반전합니다.
n이 32비트 정수일 떄 ~n-(n+1)이 됩니다. ( 반전 시 소수부는 버려집니다 )

비트 NOT 연산자~ 기호를 사용합니다.

alert( ~2 );	// -[2+1] = -3
alert( ~1 );	// -[1+1] = -2
alert( ~0 );	// -[0+1] = -1
alert( ~-1 );	// -[-1+1] = 0 (*) 비트 NOT 연산자에서 0인 경우는 n이 -1인 경우 뿐

부호가 있는 32비트 정수 중에서 결과 값을 0으로 반환 하는 건 n ==-1 가 유일하다.
이를 응용해서 indexOf-1을 반환하지 않는 경우를 검사해봅시다.

let str = "Hello";

if(~str.indexOf('Hello');) {	// 표현식이 0이 아닌 경우에는 참 = 문자열을 찾음
 alert('문자열 찾음'); 
}


/* */
1) 문자열의 위치를 찾고 위치 값을 반환 > 비트 연산자로 인해 -[찾은 값+1]을 수행한다.
2) indexOf 함수가 문자열을 찾지 못하면 -1을 반환 > -[-1+1] = 0이 됩니다.false가 되어 조건문이 만족하지 않는다.

3) -1을 제외한 나머지 값들은 문자열을 찾은 것 > 위 같은 경우에선 Hello의 위치는 str[0]
   -[0+1] = -1, truthy 값이 있으므로 가 되어 본문이 수행된다.

⚠️ NOT 비트 연산자는 현재 거의 사용하지 않는다.

~ 연산자는 오래된 스크립트에서 주로 사용했습니다. 현재는 사용하지 않습니다.
오래된 스크립트에서 ~indexOf 함수를 호출한다면, 부분 문자열이 있는지 확인하는
코드입니다.



특정 문자열의 존재 유무 파악

전체 문자열에서 찾고자 하는 문자열의 존재가 있는지 유무를 파악할 때 사용하는 메서드가
있다. str.include(substr, position) 메서드는 전체 문자열 str에서 substr
존재 유무를 확인합니다. 존재하면 true 존재하지 않으면 false를 반환합니다.

부분 문자열의 위치 정보는 필요치 않고, 포함의 유무를 확인 시 사용

alert( "Hello John".includes("Hello") ); // true
alert( "Hello".includes("John") );		// false
      
      
// ↓ 2 번째 인수를 사용하면, 해당 위치에서 부터 문자열의 유무를 검사합니다.
      

alert("Hello John".includes("John", 6));	// true
alert("Hello John".includes("John", 7));	// false, 7번쨰의 위치에는 John이 없다.

startsWith, endsWith

str.startsWith() 메서드는, str이 특정 문자열로 시작하는지 유무를 확인
str.endsWith() 메서드는, str이 특정 문자열로 끝나는지 유무를 확인

alert( "Hello John".startsWith("He") );	// true
alert( "Hello John".endsWith("ohn") );	// true



부분 문자열 추출하기

찾고자 하는 문자열의 위치 대신, 위치에 해당하는 문자열 자체를 출력합니다.
부분 문자열의 추출과 관련된 메서드는 대표적으로 세가지가 있습니다.

substring substr slice 메서드가 존재합니다.


str.slice(start [, end])

전체 문자열 str에서 startend사이에 존재하는 문자열을 반환합니다.
startend 인수는 문자열의 위치 값을 인수로 받습니다. str[0] ~ str[5]
startend보다 값이 크면 작동하지 않습니다.

let str = "stringify";
alert( str.slice(0, 5) );	// strin, str[0] ~ str[5]번째 사이에 있는 문자열 출력 
alert( str.slice(0, 1) );	// s, str[0] ~ str[1]번째 사이에 있는 문자열 출력


/* */
❗ end 위치에 있는 글자는 반환하지 않습니다.

두 번째 인수end를 생략하면, 첫 번째 인수의 위치에서부터 문자열 끝까지 반환합니다.

let str = "stringify"
alert( str.slice(2) );	// ringify, str[2] = r 위치부터 문자열 끝까지 반환

startend가 음수라면, 끝에서 부터 문자열을 추출 합니다.

let str = "stringify"
alert( str.slice(-4 , -1) );	// gif, -4(g)부터 -1(y) 사이의 문자열을 추출합니다.


/* */
❗ end가 0이라면 문자열이 추출되지 않습니다.

str.substring(start [, end])

startend사이에 있는 문자열을 반환합니다. slice 메서드와 동일한 기능이지만,
startend보다 커도 작동한다는 차이점이 있습니다.

let str = "stringify";

alert( str.substring(2, 6) );	// ring, str[2]r ~ str[6]i 사이에 있는 문자열 추출
alert( str.substring(6, 2) );	// ring, start보다 end가 크면, end를 start라고 인식

// str.slice() 메서드 사용

alert( str.slice(2, 6) );	// ring, str[2]r ~ str[6]i 사이에 문자열 추출
alert( str.slice(6, 2) );	// 빈 문자열, start가 end보다 크면 추출할 수 없음

⚠️ str.substring()str.slice차이

str.slice()
1) startend인수 보다 크면 작동하지 않는다.
2) 음수인 경우에서 사용할 수 있다. ( str.slice(-3, -1) ) 끝에서 부터 검색


str.substring()
1) start가 end인수 보다 커도 작동한다. start가 end보다 크면, end를 start로 인식
2) start나 end가 음수인 경우 0으로 판단한다. ( 두 인수가 0이라면 사용 불가 )
둘 중 하나의 인수만 0이라면 사용할 수 있다.


substr(start [, length])

start에서 시작해 length개의 글자를 반환합니다.
substr()메서드는 길이를 기준으로 문자열을 추출한다는 것에서 substring() slice()
메서드와 차이점이 있습니다.

let str = "stringify";
alert( str.substr(2, 4) );	// ring, str[2] 위치에서 부터 4개의 문자열을 추출

첫 번째 인수가 음수라면 뒤에서 부터 문자열을 추출합니다.

let str = "stringify";
alert( (str.substr(-4, 2) );	// gi, str[5], str[6] 추출

🔔 문자열 추출에 관해서 어떤 메서드가 효율적일까요?

substr메서드는 브라우저 이외의 호스트 환경에서 작동하지 않을 가능성이 있다.
남은 두 메서드 중에 음수도 인수로 받는 slice메서드를 사용하는 것이 범용성이
높습니다.

profile
프론트엔드 개발자가 되기 위한 학습 과정을 정리하는 블로그

0개의 댓글