请考虑以下代码段:
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)。
答案 0 :(得分:2)
可悲的是,你真的没有什么可以做的。作为API的客户端,您必须确保始终使用此外,
X.find("ö")
将具有实现定义的行为,因为没有guarentees如何在搜索中编码。
u8
前缀调用它,并且参数也已标准化。可以编写一个find
函数来在搜索之前对输入进行规范化,但是没有办法减轻编码中的模糊性。
我可以通过在UAX 29中实现算法来实现Unicode安全查找功能
没有必要实现它,因为它已经由Boost.Locales segment_index
实现。
我想知道是否有办法通过使用C ++ std库和boost来实现这一点 - 可能是通过将语言环境与字符串算法相结合 - 但我还没有找到解决方案。
标准库对于此是边缘无用的,据我所知Boost.Locale没有字符串搜索工具。 ICU的字符串搜索功能使用了规范等价的概念,这可能是你最好的选择。