提升区域设置规范化带状字符,但不规范化重音
Boost locale normalize strips characters but no accents
我正在尝试使用boost本地库从字符串中删除重音。
规范化功能删除带有重音的整个字符,我只想删除重音。
è -> e 例如
这是我的代码
std::string hello(u8"élève");
boost::locale::generator gen;
std::string str = boost::locale::normalize(hello,boost::locale::norm_nfd,gen(""));
期望输出:eleve
我的输出 : lve
请帮忙
这不是规范化的作用。有了nfd
,它就会进行"规范分解"。然后,您需要删除组合字符代码点。
更新从 utf8 表中收集一个松散的实现,大多数组合字符似乎以0xcc或0xcd开头:
活在魔杖盒上
// also liable to strip some greek characters that lead with 0xcd
template <typename Str>
static Str try_strip_diacritics(
Str const& input,
std::locale const& loc = std::locale())
{
using Ch = typename Str::value_type;
using T = boost::locale::utf::utf_traits<Ch>;
auto tmp = boost::locale::normalize(
input, boost::locale::norm_nfd, loc);
auto f = tmp.begin(), l = tmp.end(), out = f;
while (f!=l) {
switch(*f) {
case 'xcc':
case 'xcd': // TODO find more
T::decode(f, l);
break; // skip
default:
out = T::encode(T::decode(f, l), out);
break;
}
}
tmp.erase(out, l);
return tmp;
}
打印(在我的盒子上!
Before: "élève" 0xc3 0xa9 0x6c 0xc3 0xa8 0x76 0x65
all-in-one: "eleve" 0x65 0x6c 0x65 0x76 0x65
较旧的答案文本/分析:
#include <boost/locale.hpp>
#include <iomanip>
#include <iostream>
static void dump(std::string const& s) {
std::cout << std::hex << std::showbase << std::setfill('0');
for (uint8_t ch : s)
std::cout << " " << std::setw(4) << int(ch);
std::cout << std::endl;
}
int main() {
boost::locale::generator gen;
std::string const pupil(u8"élève");
std::string const str =
boost::locale::normalize(
pupil,
boost::locale::norm_nfd,
gen(""));
std::cout << "Before: "; dump(pupil);
std::cout << "After: "; dump(str);
}
打印,在我的盒子上:
Before: 0xc3 0xa9 0x6c 0xc3 0xa8 0x76 0x65
After: 0x65 0xcc 0x81 0x6c 0x65 0xcc 0x80 0x76 0x65
然而,在科里鲁上,这没有什么区别。这表示它取决于可用/系统区域设置。
文档说:https://www.boost.org/doc/libs/1_72_0/libs/locale/doc/html/conversions.html#conversions_normalization
Unicode 规范化是将字符串转换为 标准形式,适用于文本处理和比较。为 例如,字符"ü"可以由单个码位或 字符"U"和"Diaeresis"̈"的组合。正常化 是 Unicode 文本处理的重要组成部分。
Unicode 定义了四种规范化形式。每个特定形式都是 由传递给规范化函数的标志选择:
- NFD - 规范分解 -
boost::locale::norm_nfd
- NFC - 规范分解,然后是规范组合 - boost::locale::norm_nfc 或
boost::locale::norm_default
- NFKD - 兼容性分解 -
boost::locale::norm_nfkd
- NFKC - 兼容性分解,然后是规范组合 -
boost::locale::norm_nfkc
有关规范化形式的更多详细信息,请阅读 [本文][1]。
你可以做什么
似乎您可以通过仅执行分解(因此 NFD(然后删除任何非 alpha 的代码点来获得某种方法。
这是作弊,因为它假设所有代码点都是单单元的,这通常不是正确的,但对于示例,它确实有效:
请参阅上面的改进版本,该版本确实迭代了代码点而不是字节。
相关文章:
- C++字符*缓冲区的大小
- HEX值到wchar_t字符(UTF-8)的转换
- 为什么 Serial.println(<char[]>);返回随机字符?
- 我的字符计数代码计算错误.为什么
- 字符串-C++后显示的随机字符
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 如何在C++中从字符串中分割字符
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 指向指向字符数组的指针数组的指针
- 如何用转义符替换字符串中的所有特殊字符
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 比较字符数组
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- 如何在C++中确定文本文件中的元素是字符还是数字
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 提升区域设置规范化带状字符,但不规范化重音
- 在没有ICU或boost的情况下规范化C++中的unicode字符