2017-04-05 3 views
1

나는 중국어 문장이 있는데, 나는 중국어 문장 부호와 함께 나누고 싶다. 그러나 실패했습니다. 파일에서 utf-8 인코딩을 사용했습니다.부스트 스플릿은 중국어 문장을 분할 할 수 없습니다.

std::string src = "使用boost split失败了,不知道什么原因。有人可以告诉我吗?谢谢!"; 

boost::split(results, src, boost::is_any_of(",.,。")); 

분할 결과는 다음과 같습니다

["使用boost split失败了", "", "", "不知道�", "么原因", "", "", "有人可以告诉我吗", "", "�谢谢", "", "�"] 

부스트 분할 중국어 단어를 분할 할 수 있습니까? 어떤 사람이 이유를 말해 줄 수 있습니까? 고맙습니다.

답변

1

은 내가 C++ (11) 정규식이 문제를 해결할 수있는 것을 발견 :

std::regex regex(",|。|!|?"); 
std::string src = "使用boost split失败了,不知道什么原因。有人可以告诉我吗?谢谢!"; 

std::sregex_token_iterator iterator(src.begin(), src.end(), regex, -1); 
std::sregex_token_iterator end; 

for (; iterator != end; ++iterator) { 
    std::string res = *iterator; 
    std::cout << res << std::endl; 
} 

results: 
使用boost split失败了 
不知道什么原因 
有人可以告诉我吗 
谢谢 

왜 부스트 할 수 없습니다? 잘못된 방법을 사용 했습니까?

+0

여기서 정규 표현식은 일치하는 올바른 바이트 시퀀스로 패턴을 명시 적으로 분할합니다 (패턴의 바이트를 문자처럼 일치시키는 대신) . 이것은 [입력/패턴 문자열의 정규화] (https://en.wikipedia.org/wiki/Unicode_equivalence)에 따라 달라집니다. – sehe

1

부스트 스 트림은 문자열을 std :: strings : char : 대략 "바이트"(또는 UTF-8 코드 단위)의 문자열로 취급합니다.

그러나, 소스/패턴의 코드 포인트의 대부분은 멀티 바이트 문자는이 사실이 무엇을 (UTF-8 소스 파일을 가정)입니다 :

당신이 볼 수 있듯이
std::string src { 
    0xe4, 0xbd, 0xbf, 0xe7, 0x94, 0xa8, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x20, 
    0x73, 0x70, 0x6c, 0x69, 0x74, 0xe5, 0xa4, 0xb1, 0xe8, 0xb4, 0xa5, 0xe4, 
    0xba, 0x86, 0xef, 0xbc, 0x8c, 0xe4, 0xb8, 0x8d, 0xe7, 0x9f, 0xa5, 0xe9, 
    0x81, 0x93, 0xe4, 0xbb, 0x80, 0xe4, 0xb9, 0x88, 0xe5, 0x8e, 0x9f, 0xe5, 
    0x9b, 0xa0, 0xe3, 0x80, 0x82, 0xe6, 0x9c, 0x89, 0xe4, 0xba, 0xba, 0xe5, 
    0x8f, 0xaf, 0xe4, 0xbb, 0xa5, 0xe5, 0x91, 0x8a, 0xe8, 0xaf, 0x89, 0xe6, 
    0x88, 0x91, 0xe5, 0x90, 0x97, 0xef, 0xbc, 0x9f, 0xe8, 0xb0, 0xa2, 0xe8, 
    0xb0, 0xa2, 0xef, 0xbc, 0x81 
}; 

boost::split(results, src, boost::is_any_of({ 
    0x2c, 0x2e, 0xef, 0xbc, 0x8c, 0xe3, 0x80, 0x82 
})); 

, 그것은에 분할 8 바이트 (0x2c, 0x2e, 0xef, 0xbc, 0x8c, 0xe3, 0x80, 0x82)는 예상했던 4 가지 코드 포인트가 아닙니다.

나는 모든 유니 코드를 지원하는 Boost Regex를 기억합니다. 단, 모든 문자열을 UTF32로 변환하고 이미 사용한 알고리즘을 사용할 수는 있습니다.

당신은 와이드 문자의 시퀀스로 인코딩 된 문자열을 검색 할 수 있습니다 http://www.boost.org/doc/libs/1_63_0/libs/regex/doc/html/boost_regex/unicode.html

를 참조하십시오, 많은 플랫폼에서 UTF-8 또는 UTF-16를 검색 할 수 없습니다.

어쨌든 UTF32로 변환해야합니다. 또는 ICU 통합을 boost :: u32regex와 함께 사용할 수 있습니다.

+0

UTF-32는 더 좋지 않습니다. 여전히 여러 개의 코드 단위로 구성된 문자가 있습니다 (sic?). 먼저 유니 코드 문자열을 정규화해야합니다. – rubenvb

+0

나는 이것에 동의하지 않을 것이다. 하지만 그래, 그건 사실이야. – sehe

+0

std :: string 데이터를 저장하는 데 사용되는 char, 여기에 utf-8로 인코딩 된 문장을 사용했습니다. utf-8 크기가 char 크기를 오버플로했습니다. 어쩌면 문제가 생겼을 수도 있습니다. –