[C++] Tokenizing : 문자열 파싱 _ split (with find & substr)

    반응형

    [C++] Tokenizing

    *개인적인 공부 내용을 기록하는 용도로 작성한 글 이기에 잘못된 내용을 포함하고 있을 수 있습니다.

    _contents

    #1 Tokenizing

    #2 find & substr function

    #3 split

    *공백을 기준으로 2개의 token 생성

    *공백을 기준으로 3개 이상의 token 생성


    #1 Tokenizing

    Tokenizing이란 Text를 delimiter(공백, 특수문자 등)을 기준으로 여러개의 Token으로 나누는 것을 의미한다.

    그리고 이런 Tokenizing을 수행하는 것을 Tokenizer 이라고 하는데 대표적으로 split 함수가 있다.

    하지만 JAVA, Python과 같은 언어들과는 달리 C++은 별도의 Tokenizer를 제공하지 않는다. 하지만 find, substr 함수를 사용하여 Tokenizing을 구현할 수 있다.


    #2 find & substr function

    Tokenizing을 구현하기 이전에 find / substr 함수에 대해 간략하게 알아 보도록 하자.

    문자열이름.find("탐색할 문자열");
    // 탐색 성공 : 찾고자 하는 문자의 첫 번째 인덱스 주소 반환
    // 탐색 실패 : string::npos 리턴 (무작위 long long 가비지 값)

    string.find 함수는 특정 문자열에서 원하는 문자열을 찾는 기능을 수행하는 함수로, 문자열 탐색에 성공했을 경우 문자의 첫 번째 인덱스 주소를 반환하고, 문자열 탐색에 성공하지 못했을 경우에는 string::npos를 리턴한다. _link

    문자열이름.substr(시작위치, 길이);
    // 문자열의 시작 위치로 부터 길이 만큼의 문자열을 잘라낸다.

    substr 함수는 지정된 길이의 문자열을 잘라내는 기능을 수행하는 함수이다.첫 번째 인자로 시작 위치두 번째 인자로 길이를 넣어 주어 시작 위치부터 길이에 해당하는 문자열을 취득한다.


    #3 split

    * 3.1 공백을 기준으로 2개의 token 생성

    앞서 공부한 find, substr 함수를 이용해 "Let's learn!" 문자열(Text)를 공백(delimiter)을 기준으로 2개의 Token(Let's , Learn!)으로 나누어 보도록 하겠다.

     

    우선 find 함수를 이용해 공백의 인덱스를 delimiter에 저장한다.

    	string str = "Let's Learn";
    	int delimiter = str.find(' '); // 5

     

    다음으로 substr 함수를 이용해 from 문자열에 공백 앞의 문자열을 저장하고, to 문자열에는 delimiter + 1 즉, 공백 이후의 문자열을 저장한 뒤 출력한다. 

    	string from = str.substr(0, delimiter); // "Let's"
    	string to = str.substr(delimiter + 1); // "Learn"
    	cout << "from : " << from << endl <<
    		"to : " << to << endl;
    [출력결과] 
    from : Let's
    to : Learn

     

    * 3.2 공백을 기준으로 3개 이상의 token 생성

    이번에는 "Let's Learn Tokenizing!"문자열을 3개의 토큰으로 나누어 보도록 하겠다. 2개의 token으로 나누는 것 보다 약간 복잡하다.

    우선 잘라낸 token을 저장할 tok vector를 선언한 뒤, insert 함수를 이용해 문자열 마지막에 공백을 추가해 준다. (공백을 추가해 주지 않으면 마지막 문자열이 들어가지 않는다.)

    다음으로 pos가 string::npos를 가리킬 때 (string.find 함수는 탐색에 실패하면 string::npos를 리턴한다.) 즉, 더 이상 delimiter(공백)을 찾지 못할 때 까지 while 반복문을 돌린다.

    그리고 첫 공백이 나올 때 까지 문자열을 잘라내어 tok vector에 push한 뒤, 잘라낸 문자열은 string.erase 함수를 사용해 삭제한다.

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    int main(){
    	string str = "Let's Learn Tokenizing!";
    	str.insert(str.length(), " "); // 문자열 마지막에 공백 추가
    	string delimiter = " ";
    	vector<string> tok{}; // str을 tokenizing한 token을 저장할 vector	
    	size_t pos = 0;	
    	// pos가 string::npos를 가리킬 때, 즉, 문자열의 끝에 도달할 때 까지 탐색
    	while((pos = str.find(delimiter)) != string::npos){
    		// 0 ~ 공백이 나올 때 까지 문자열을 잘라내어 tok vector에 push
    		tok.push_back(str.substr(0, pos));
    		// 잘라낸 문자열은 erase 함수를 이용해 삭제
    		str.erase(0, pos + delimiter.length());
    	}
    	
    	for(const auto &s : tok)
    		cout << s << endl;
    	
    	return 0;
    }
    [실행결과]
    Let's
    Learn
    Tokenizing!
    반응형

    댓글

    Designed by JB FACTORY