본문으로 바로가기

indexOf, lastIndexOf 를 이용한 문자열 검색




문자열 부분 문자열 검색하기

대상 문자열 안에서 특정한 부분 문자열이 있는지를 찾고자 하는 경우에는 String 객체의 내장 메서드 indexOf 를 사용하면 부분 문자열의 위치를 알 수 있습니다.

javascript
var testValue = 'This is the Cookbook';
var subValue = 'Cookbook';

var iValue = testValue.indexOf(subValue);
console.log(iValue);

// String 객체의 indexOf 메서드는 인덱스 혹은 부분 문자열의 첫 번째 글자가 있는 위치를 나타내는 숫자를 반환하고, 문자열에서 첫 번째
// 문자의 인덱스는 0 입니다.

// 부분 문자열이 대상 문자열 안에 있는지 없는지 확인하기 위해서는 반환되는 값이 -1 인지 살펴보면 됩니다
if (iValue != -1) {
	console.log('찾고자 하는 부분 문자열이 있습니다.');
}

// indexOf 메서드는 두 개의 인자를 갖습니다.
// 첫 번째 인자는 찾고자 하는 부분 문자열이고, 두 번째 인자는 검색을 시작할 위치의 인덱스 값입니다.
// 두 번째 인자는 생략 가능합니다.
var str = 'Have you had a dinner?';
var subStr = 'dinner';
var iVal = str.indexOf(subStr, 8);
console.log(iVal); // 15 => 부분 문자열의 인덱스 15를 반환

// indexOf 메서드는 왼쪽에서 오른쪽으로 탐색합니다. 그러나 때로는 문자열을 오른쪽에서 왼쪽으로 탐색하고 싶을 때가 있습니다.
// 이럴 경우에는 String 객체의 또 다른 메서드인 lastIndexOf 를 사용하면 됩니다.
// lastIndexOf 는 가장 마지막에 나타난 부분 문자열의 인덱스 위치를 반환합니다.

var testStr = 'I have been there';
var findStr = 'been';
var findIndex = testStr.lastIndexOf(findStr);
console.log(findIndex); // 7

// lastIndexOf 의 두 번째 인수는 indexOf 에서와 마찬가지로 생략할 수 있으며, 검색 시작 위치를 전달 받습니다.
// 검색을 시작할 위치는 오른쪽 부터 셈한 값입니다.
console.log(testStr.lastIndexOf('have', 5)); // 2
console.log(testStr.lastIndexOf('there', 7)); // -1 반환, 찾지 못함
// 7인 인덱스 위치에서 오른쪽 부터 검색하므로 찾지 못함
// 즉,인덱스 7 의 위치에서 'I have b' 의 b 위치부터 오른쪽에서 왼쪽으로 검색하기 때문에 찾고자 하는 문자열이 없어서 -1 을 반환



문자열에서 부분 문자열을 추출하는 방법

여러 개의 문장으로 이루어진 문자열이 있고, 그 중 하나의 문장에 어떤 목록이 포함되어 있다고 가정합니다.

그리고 목록은 콜론(:)으로 시작하고 마침표(.)로 끝납니다.

이때 이러한 문자열을 추출하고 하는 경우에는 indexOf 메서드를 사용하여 콜론의 위치를 알아낸 후,

다시 indexOf 메서드를 사용하여 콜론 다음에 오는 마침표의 위치를 찾습니다.

그리고 나서 두 개의 위치를 substring 메서드와 함께 사용하면 문자열을 추출할 수 있습니다.

javascript
var sentence = 'A list of item: cherries, oranges, apples, bananas.';
var start = sentence.indexOf(':'); // 콜론의 위치를 알아낸다.
var end = sentence.indexOf('.', start+1); // 마침표의 위치를 알아내는데, 두 번째 인자로 콜론이 위치한 인덱스 위치 다음부터 찾을 인덱스를 인자로 정의한다.
console.log(start, end); // 14, 50

// 목록의 시작 위치와 끝 위치를 구했다면 다음은 substring 메서드를 사용하는데 substring 메서드의 첫 번째 인자와 두 번째 인자는
// 각각 추출할 문자열의 시작과 끝 위치를 나타내는 인덱스값입니다.
var list = sentence.substring(start+1, end);
console.log(list); // ' cherries, oranges, apples, bananas' 를 반환

// String.split 같은 메서드를 사용하면 목록의 값을 각각 분리할 수도 있습니다.
var fruits = list.split(',');
console.log(fruits);
// 콤마(,)를 구분자로 [" cherries", " oranges", " apples", " bananas"] 배열이 반환됩니다.

console.log('test box group'.split(' ')); // 빈 문자열을 구분자로 배열이 반환



문자열이 존재하는지 또는 빈 문자열인지 확인하기

변수가 정의되어 있으며 문자열이 들어 있는지 또는 비어 있는지를 확인하고자 하는 경우에는 다음과 같이 작성할 수 있습니다.

javascript
// 변수가 존재하고 문자열이 0 보다 큰 길이를 가지고 있으면 참
var unknownVal = '';
if ( (typeof unknownVal != 'undefined') && (typeof unknownVal.valueOf() == 'string') && (unknownVal.length > 0) ) {
	console.log('문자열이 존재합니다.');
}

typeof 연산자, valueOf 메서드, String 객체의 length 속성을 사용하면 변수가 정의되어 있으며 문자열이 들어 있는지 혹은 비어 있는지를 확인하는 조건문을 작성할 수 있습니다.

(valueOf 메서드는 모든 자바스크립트 객체가 공유하는 메서드입니다.)

length 를 사용하면 문자열의 길이를 알 수 있고, 문자열 변수가 빈 문자열인지 아닌지를 확인할 수 있습니다(빈 문자열이면 length 가 0)

그러나 문자열을 다룰 때 변수가 정의되어 있지 않다면 undefined 란 오류가 발생합니다.

그래서 변수가 정의되어 있는지 확실하지 않다면 문자열 길이를 테스트할 수도 없습니다.

따라서 문자열의 길이를 테스트하기에 앞서 변수가 존재하는지에 대한 테스트 과정을 수반할 필요가 있습니다.

이런 특성 덕분에 정의되지 않은 변수의 속성에 접근하는 오류를 예방할 수 있습니다.

그리고 또 하나 고려해야할 점은 정의된 변수가 문자열이 아닐 경우를 대비해야 합니다.

예를 들어 변수가 숫자라면 이런 경우 숫자에는 length 속성이 없기 때문에 조건문은 거짓이 됩니다.

그러나 변수의 값이 String 객체라면 어떨까요?

변수의 타입을 정확하게 알 수 없다면 문자열 길이를 테스트하기에 앞서 명시적으로 변수의 데이터 타입이 'string' 인지 테스트해야 합니다.


테스트가 성공하면 예상했던 대로 길이가 0 보다 큰 문자열을 얻을 수 있습니다.

하지만 변수가 문자열 리터럴이 아닌 String 객체라면 typeof 연산자는 'string' 대신 'object'를 반환할 것입니다.

이것이 바로 또 다른 자바스크립트 메서드인 valueOf 를 같이 사용해야 하는 이유입니다.

valueOf 메서드는 모든 자바스크립트 객체에서 사용가능하며, 객체가 무엇이든 원시 자료형을 반환합니다.

Number, String, Boolean 에 대해서는 각각의 원시 자료형을 반환하고 Function 에 대해서는 함수의 내용을 반환합니다.

변수가 이미 문자열 리터럴일 경우에는 valueOf 메서드를 사용하면 임시로 String 래퍼객체로 감싼 후 valueOf 메서드를 실행하므로

이 경우에도 반환되는 값은 문자열 리터럴입니다.

그래서 위의 조건문은 변수가 정의되었는지 확인하고, 정의되어있다면 valueOf 메서드를 사용하여 String 객체 혹은 문자열 리터럴인지 확인한 후 문자열의 길이가 0 보다 큰자 확인하는 것입니다.


일반적으로 빈 문자열인지 아닌지 확인하기 위해 변수가 정의되었는지 여부와 문자열 길이만 테스트합니다.



Jaehee's WebClub