2009-05-21 2 views
4

나는 부스트 문자열 라이브러리를 가지고 놀고 있으며 분할 방법의 단순함을 발견했습니다. 좋은 간결 것부스트 분할로 escaped_list_separator 사용

string delimiters = ","; 
    string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\""; 
    // If we didn't care about delimiter characters within a quoted section we could us 
    vector<string> tokens; 
    boost::split(tokens, str, boost::is_any_of(delimiters)); 
    // gives the wrong result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters", " inside a quote\""} 

... 그러나 그것은 따옴표와 함께 작동하지 않는 것 대신 나는 다음과 같은

string delimiters = ","; 
string str = "string, with, comma, delimited, tokens, \"and delimiters, inside a quote\""; 
vector<string> tokens; 
escaped_list_separator<char> separator("\\",delimiters, "\""); 
typedef tokenizer<escaped_list_separator<char> > Tokeniser; 
Tokeniser t(str, separator); 
for (Tokeniser::iterator it = t.begin(); it != t.end(); ++it) 
    tokens.push_back(*it); 
// gives the correct result: tokens = {"string", " with", " comma", " delimited", " tokens", "\"and delimiters, inside a quote\""} 
내 질문은 분할 할 수있다

또는 다른처럼 뭔가를해야 구분 기호를 인용 할 때 표준 알고리즘을 사용합니까? Purpledog 덕분에 나는 원하는 결과를 성취하기 위해 비추천하지 않는 방법을 이미 가지고있다. 나는 그것을 꽤 복잡하다고 생각한다. 그리고 그것을 더 단순하고 우아한 해결책으로 대체 할 수 없다면, 일반적으로 그것을 사용하지 않고 일반적으로 사용하지 않을 것이다. 또 다른 방법.

편집 : 결과를 표시하고 질문을 명확히하기위한 코드가 업데이트되었습니다.

답변

5

부스트 :: 분할 방법을 사용하여이 작업을 수행 할 수있는 간단한 방법이 있다고 보이지 않는다. 내가이 일을 찾을 수있는 코드의 짧은 조각은 미미한 더 자세한 원래 조각보다

vector<string> tokens; 
tokenizer<escaped_list_separator<char> > t(str, escaped_list_separator<char>("\\", ",", "\"")); 
BOOST_FOREACH(string s, escTokeniser) 
    tokens.push_back(s); 

입니다

vector<string> tokens; 
boost::split(tokens, str, boost::is_any_of(",")); 
2

boost :: string 라이브러리에 대해서는 잘 모릅니다 만 boost regex_token_iterator를 사용하면 정규 표현식의 단락 문자를 표현할 수 있습니다. 그래서 예, 따옴표 붙은 구분 기호와 훨씬 복잡한 것들을 사용할 수 있습니다.

이전에는 사용되지 않는 regex_split를 사용 했었던 점에 유의하십시오. 여기

가 부스트 문서에서 가져온 예입니다 : 프로그램이 안녕하세요 세계로 시작되는 경우

#include <iostream> 
#include <boost/regex.hpp> 

using namespace std; 

int main(int argc) 
{ 
    string s; 
    do{ 
     if(argc == 1) 
     { 
     cout << "Enter text to split (or \"quit\" to exit): "; 
     getline(cin, s); 
     if(s == "quit") break; 
     } 
     else 
     s = "This is a string of tokens"; 

     boost::regex re("\\s+"); 
     boost::sregex_token_iterator i(s.begin(), s.end(), re, -1); 
     boost::sregex_token_iterator j; 

     unsigned count = 0; 
     while(i != j) 
     { 
     cout << *i++ << endl; 
     count++; 
     } 
     cout << "There were " << count << " tokens found." << endl; 

    }while(argc == 1); 
    return 0; 
} 

인수로 출력은 다음과 같습니다

hello 
world 
There were 2 tokens found. 

부스트를 변경 :: 정규식 재 ("\ s +"); into boost :: regex re ("\", \ "");은 따옴표로 구분 된 구분 기호를 분리합니다. 인수로 안녕하세요 ","세계로 프로그램을 시작하면 될 것이다 :

hello 
world 
There were 2 tokens found. 

하지만 난 당신이 그런 일을 처리 할 생각 : "안녕하세요", "세계"하는 경우 하나 개의 솔루션은 다음과 같습니다 혼수와

  1. 분할은
  2. 은 다음 ""(아마도 사용하여 부스트/알고리즘/문자열/trim.hpp 또는 정규식 라이브러리)를 제거합니다.

편집 : 추가 프로그램 출력

+0

출력 결과를 함께 표시하면 제공 한 예가 향상됩니다. 코드가 무엇을하는지이 페이지를 찾은 모든 사람에게 풍부하게 알려주는 것입니다. –

2

이 명시 적 루프없이 제이미 쿡의 대답과 같은 결과를 얻을 것입니다 .

tokenizer<escaped_list_separator<char> >tok(str); 
vector<string> tokens(tok.begin(), tok.end()); 

escaped_list_separator<char>("\\", ",", "\"")에 토크 나이 생성자의 두 번째 매개 변수의 기본값은 그래서 필요는 없습니다. 쉼표 나 따옴표에 대한 요구 사항이 다를 경우가 아니면

관련 문제