在 ASCII/UTF8 中转换带有重音符号的 Unicode 字母

Posted

技术标签:

【中文标题】在 ASCII/UTF8 中转换带有重音符号的 Unicode 字母【英文标题】:converting Unicode letters with accents in ASCII/UTF8 【发布时间】:2015-01-11 20:56:11 【问题描述】:

我正在寻找一种技术来转换由服务器发送的包含如下内容的字符串(JSON): ...."Test \u00e9\u00e9\u00e9"..... 类似:“Test ééé” 我找到了解决方案:boost::replace_all(listFolder, "\\u00e9", "é"); 而且我正在将这个提升功能与其他字母 àùèê 等一起使用......这很痛苦!

不知道有没有自动进行这种转换的函数。

否则,我想告诉你一些其他事情,如果我使用此功能,服务器将正确处理我发送给它的字符串并包含带重音的字母:

std::string fromLocale(std::string localeStr)

    boost::locale::generator g;
    g.locale_cache_enabled(true);
    std::locale loc = g(boost::locale::util::get_system_locale());
    return boost::locale::conv::to_utf<char>(localeStr,loc);

不幸的是,该代码的逆代码无法处理服务器发送的字符串。

std::string toLocale(std::string utf8Str)

    boost::locale::generator g;
    g.locale_cache_enabled(true);
    std::locale loc = g(boost::locale::util::get_system_locale());
    return boost::locale::conv::from_utf<char>(utf8Str,loc);

【问题讨论】:

我不太清楚你在问什么。看看这些用于解码 JSON (Unicode) 转义的 sn-ps:append_utf8 in this sample 读者注意到,正如@sehe 解释的那样,描述为"Test \u00e9\u00e9\u00e9" 的字符串是字符串"Test \\u00e9\\u00e9\\u00e9",即\、u、0、0、e 和9 是单独的字符。 是的,干杯。 - 阿尔夫 【参考方案1】:

JSON specification 允许 Unicode 字符的 "\uXXXX" 序列(以及其他 \X 转义序列)。如果您没有使用现有的 JSON 解析器来处理此类序列的解码,则必须手动对其进行解码,例如:

// JSON uses Unicode, but is commonly encoded as UTF-8. However, Unicode
// characters that are encoded in "\uXXXX" format are expressed as UTF-16
// codeunit values, using surrogate pairs for codepoint values U+10000 and
// higher. This example uses C++11's std::u16string to handle UTF-16 parsing.
// If you are not using C++11 or later, you can replace it with std::wstring
// on platforms where wchar_t is 16bit, for instance.  If you want to handle
// the JSON using std::string/UTF-8 instead, you will have to tweak this
// parsing accordingly...

std::u16string str = ...; // JSON quoted-string value, eg: "Test \u00e9\u00e9\u00e9"...
std::u16string::size_type idx = 0;
do

    idx = str.find(u'\\', idx);
    if (idx == std::u16string::npos) break;

    std::u16string replaceStr;
    std::u16string::size_type len = 2;

    char16_t ch = str.at(idx+1);
    switch (ch)
    
        case u'\"':
        case u'\\':
        case u'/':
            replaceStr = ch;
            break;

        case u'b':
            replaceStr = u'\b';
            break;

        case u'f':
            replaceStr = u'\f';
            break;

        case u'n':
            replaceStr = u'\n';
            break;

        case u'r':
            replaceStr = u'\r';
            break;

        case u't':
            replaceStr = u'\t';
            break;

        case u'u':
        
            std::u16string hexStr = str.substr(idx+2, 4);
            len += hexStr.size();

            std::basic_istringstream<char16_t> iss(hexStr);
            unsigned short value;
            iss >> std::hex >> value;
            if (!iss)
            
                // illegal value, do something
            

            replaceStr = (char_t) value;
            break;
        

        default:
            // illegal sequence, do something
            break;
    

    str.replace(idx, len, replaceStr);
    idx += replaceStr.size();

while (true);

【讨论】:

【参考方案2】:

我找到的解决方案是使用 RapidJson。

【讨论】:

以上是关于在 ASCII/UTF8 中转换带有重音符号的 Unicode 字母的主要内容,如果未能解决你的问题,请参考以下文章

Bibtex 错误地编译重音符号

带有重音符号的Python转储json [重复]

用 gsub 替换带有重音符号的多个字母

(Obj-C) 从 NSHTTPURLResponse (allHeaderFields) 解码带有重音符号的 JSON

使用正则表达式剥离字符失败,使用带有变音符号,撇号,重音符号等的文字字符

带重音符号的 QProcess 输入字符串