如何将 unicode 字符串转换为其 unicode 转义?
Posted
技术标签:
【中文标题】如何将 unicode 字符串转换为其 unicode 转义?【英文标题】:How to convert a unicode string to its unicode escapes? 【发布时间】:2010-07-09 09:02:11 【问题描述】:假设我有一个文本“Բարև Hello Здравствуй”。 (我将此代码保存在 QString 中,但如果您知道在 c++ 代码中存储此文本的其他方法,不客气。)如何将此文本转换为 Unicode 转义,如“\u1330\u1377\u1408\u1415 Hello \ u1047\u1076\u1088\u1072\u1074\u1089\u1090\u1074\u1091\u1081"(见here)?
【问题讨论】:
QString
很好。作为替代方案,您可以使用 ICU 库中的 UnicodeString
。
那不是“UTF-8 编码”,实际上你的例子与 UTF-8 完全没有关系。您所描述的是Unicode转义。据我所知,它们并没有被普遍使用。例如,Java 在其源文件中使用它们。
好的,我更改代码->unicode 转义!
我在您的问题中没有看到任何与 UTF-8 相关的内容。 QString
使用 UTF-16 编码,期望的结果似乎是对非 ASCII 字符使用转义序列的表示。有趣的是,这个问题似乎与***.com/questions/3147900 相反。
接缝它只是默认的。但您可以将其设置为 UTF-8 或其他编码。
【参考方案1】:
#include <cstdio>
#include <QtCore/QString>
#include <QtCore/QTextStream>
int main()
QString str = QString::fromWCharArray(L"Բարև Hello Здравствуй");
QString escaped;
escaped.reserve(6 * str.size());
for (QString::const_iterator it = str.begin(); it != str.end(); ++it)
QChar ch = *it;
ushort code = ch.unicode();
if (code < 0x80)
escaped += ch;
else
escaped += "\\u";
escaped += QString::number(code, 16).rightJustified(4, '0');
QTextStream stream(stdout);
stream << escaped << '\n';
请注意,这会循环 UTF-16 代码单元,而不是实际的代码点。
【讨论】:
我收到链接错误。这是因为 ch.unicode() 我猜。 链接QtCore
(例如g++ -lQtCore
)。
还有QString::fromWCharArray会导致以下问题:error: conversion to execution character set: Illegal byte sequence
@Narek:是的,我在发布之前对其进行了测试。 (有时我会在脑海中写出代码,但这段代码太复杂了。)我还在 Python 中测试了结果,它使用相同的转义机制,并返回了输入字符串。请指定您的编译器和操作系统。我的是 Linux 上的 GCC 4.3.3。
根据您将使用它的目的,您可能还希望将原始“str”中的任何单个斜杠 () 转换为“转义”字符串中的两个斜杠 (\),因此以便您以后可以正确地对其进行转义。【参考方案2】:
我假设您正在生成代码(也许是 javascript?)
QString
就像QChar
的集合。循环遍历内容,并在每个QChar
上调用unicode
方法以获取ushort
(16 位整数)值。
然后将每个字符格式化为"\\u%04X"
,即\u
,后跟4位十六进制值。
注意。您可能需要交换两个字节(两个十六进制字符)以获得正确的结果,具体取决于您运行的平台。
【讨论】:
不确定这是否适用于 BMP。 U+10000 等字符在 RTF 文件中是如何编码的? 代码不可读,请使用代码格式(只需编辑您的原始问题)。再说一遍,它与 UTF-8 无关,所以我很确定你不需要setCodecForTr
的东西。
您好 Narek,如果您从工具中收到错误消息,最好发布它的文本以便人们可以帮助您。
另外,您似乎试图通过将我建议的格式字符串作为字符串传递给流来使用它。那只会将其输出为字符串。我用旧的sprintf
样式编写了格式字符串,因此您可以尝试使用它,或者您可以查看如何使用std::stringstream
来实现。【参考方案3】:
wchar_t *input;
wstring output;
for (int i=0; i<str_len; i++)
wchar_t code[7];
swprintf(code, 7, L"\\u%0.4X",input[i]);
output += code;
【讨论】:
【参考方案4】:我已经用这段代码解决了这个问题:
已编辑为更好的版本:(我只是不想将拉丁符号转换为 Unicode,因为它会占用额外的空间,而对我的问题没有好处(想提醒我要生成 Unicode RTF)。
int main(int argc, char *argv[])
QApplication app(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QString str(QWidget::tr("Բարև (1-2+3/15,69_) Hello [2.63] Здравствуй"));
QString strNew;
QString isAcsii;
QString tmp;
foreach(QChar cr, str)
if(cr.toAscii() != QChar(0))
isAcsii = static_cast<QString>(cr.toAscii());
strNew+=isAcsii;
else
tmp.setNum(cr.unicode());
tmp.prepend("\\u");
strNew+=tmp;
QMessageBox::about(0,"Unicode escapes!",strNew);
return app.exec();
感谢@Daniel Earwicker 的算法,当然还有+1。
顺便说一句,您需要为文本编辑器编码指定 UTF-8。
【讨论】:
其实你可以用QString::fromUtf8("Բարև (1-2+3/15,69_) Hello [2.63] Здравствуй")
【参考方案5】:
您必须首先确定文本“Բարև Hello Здравствуй”使用哪种编码,看起来像俄语,可能是 Win Code Page 1251。或 UTF-8 或其他。 然后使用窗口函数 MultiByteToWideChar 和所需的输入,例如应用代码页、原始名称等。
希望对你有帮助。
【讨论】:
是的!刚接触 QT...谢谢!【参考方案6】:我的解决方案:
std::wstring output;
QString result;
QTextCodec::setCodecForLocale ( QTextCodec::codecForName ( "UTF-8" ) );
for( uint i = 0; wcslen( input ) > i; ++i )
if( isascii( input[ i ] ) )
output.reserve( output.size() + 1 );
output += input[ i ];
else
wchar_t code[ 7 ];
swprintf( code, 7, L"\\u%0.4X", input[ i ] );
output.reserve( output.size() + 7 ); // "\u"(2) + 5(uint max digits capacity)
output += code;
result.reserve( output.size() );
result.append( QString::fromStdWString( output ) );
适用于俄语正确。 变换
hello
привет
进入
hello
\\u043F\\u0440\\u0438\\u0432\\u0435\\u0442
【讨论】:
以上是关于如何将 unicode 字符串转换为其 unicode 转义?的主要内容,如果未能解决你的问题,请参考以下文章
扩展的 ASCII 字符,例如欧元符号被转换为其 unicode 等价物
Python3 - 将非 ascii 字符替换为其 unicode 代表值? [复制]