2017-04-05 72 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

Boost split认为将字符串视为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有更多的UNICODE支持,除此之外你可以尝试将所有字符串转换为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?),这将要求你首先规范unicode字符串。 – rubenvb

+0

我不同意这不会更好。但是,这也是真的。 – sehe

+0

std :: string用char来存储数据,这里我用utf-8编码的句子。 utf-8大小溢出了字符大小。也许它导致了这个问题。 –