使用boost和标准C ++进行Unicode安全查找

时间:2015-09-30 12:44:01

标签: c++ boost unicode

请考虑以下代码段:

namespace bl = boost::locale;
static bl::generator gen;
static auto loc = gen("en_US.UTF-8");
std::string foo8 = u8"Föo";
std::string deco = bl::normalize(foo8,bl::norm_nfd,loc);
std::string comp = bl::normalize(foo8,bl::norm_nfc,loc);
std::cout << "decomposed: " << deco.find("o") << ", composed: " << comp.find("o") <<"\n";

这给出:“分解:1,组成:3”。

现在,正确的答案取决于整理因素,但对于大多数情况,后者将是我想要的 - o的第一个位置,而不是分解的ö的第一部分。显然,对于这个例子,我可以将字符串规范化为NFC以确保我得到所需的结果,但是这对于无法组成字素集群的情况不起作用。

此外,X.find(“ö”)将具有实现定义的行为,因为不能保证在搜索中如何编码ö。

我可以通过在UAX 29中实现算法或通过规范化搜索字符串来实现Unicode安全查找功能,但我想知道是否有办法通过使用C ++ std库和boost来实现这一点 - 也许通过将语言环境与字符串算法相结合 - 但我还没有找到解决方案。

任何人都有明确的答案吗?我知道我可以使用ICU,并且boost :: locale是一个围绕ICU库的c ++友好包装器(至少如果你想要完全支持unicode)。

1 个答案:

答案 0 :(得分:2)

  

此外,X.find("ö")将具有实现定义的行为,因为没有guarentees如何在搜索中编码。

可悲的是,你真的没有什么可以做的。作为API的客户端,您必须确保始终使用u8前缀调用它,并且参数也已标准化。可以编写一个find函数来在搜索之前对输入进行规范化,但是没有办法减轻编码中的模糊性。

  

我可以通过在UAX 29中实现算法来实现Unicode安全查找功能

没有必要实现它,因为它已经由Boost.Locales segment_index实现。

  

我想知道是否有办法通过使用C ++ std库和boost来实现这一点 - 可能是通过将语言环境与字符串算法相结合 - 但我还没有找到解决方案。

标准库对于此是边缘无用的,据我所知Boost.Locale没有字符串搜索工具。 ICU的字符串搜索功能使用了规范等价的概念,这可能是你最好的选择。