c++ - 将任何 Unicode 字符串转换为 int

标签 c++ qt unicode numbers

我有一个表示数字的任意 Unicode 字符串,例如“2”、“٢”(U+0662,阿拉伯印度数字二位)或“Ⅱ”(U+2161,罗马数字二)。我想将该字符串转换为一个 int。我不关心特定的语言环境(输入可能不在当前语言环境中);如果它是一个有效的数字,那么它应该被转换。

我尝试了 QString.toIntQLocale.toInt,但它们似乎无法完成工作。示例:

bool ok;
int n;
QString s = QChar(0x0662); // ARABIC-INDIC DIGIT TWO

n = s.toInt(&ok); // n == 0; ok == false

QLocale anyLocale(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
n = anyLocale.toInt(s, &ok); // n == 0; ok == false

QLocale cLocale = QLocale::C;
n = cLocale.toInt(s, &ok); // n == 0; ok == false

QLocale arabicLocale = QLocale::Arabic; // Specific locale. I don't want that.
n = arabicLocale.toInt(s, &ok); // n == 2; ok == true

我是否缺少某个功能?

我可以尝试所有语言环境:

QList<QLocale> allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
for(int i = 0; i < allLocales.size(); i++)
{
    n = allLocales[i].toInt(s, &ok);
    if(ok)
        break;
}

但这感觉有点老套。此外,它不适用于所有字符串(例如罗马数字,但这是一个可以接受的限制)。这样做是否有任何陷阱,例如不同语言环境中的冲突规则(参见土耳其语与非土耳其语字母大小写规则)?

最佳答案

我不知道有任何现成的包可以做到这一点(但是 也许 ICU 支持它),但如果你真的这样做并不难 想要。首先,您应该下载 UnicodeData.txt 文件 来自 http://www.unicode.org/Public/UNIDATA/UnicodeData.txt . 这是一个易于解析的 ASCII 文件;确切的语法是 在 http://www.unicode.org/reports/tr44/tr44-10.html 中描述, 但出于您的目的,您需要知道的是每一行 该文件由分号分隔的字段组成。首先 字段包含十六进制的字符代码,第三个字段 “一般类别”,如果第三个字段是“Nd”(数字, 十进制),第七个字段包含十进制值。

这个文件可以很容易地使用 Python 或其他一些工具来解析 脚本语言,构建映射表。你会想要一些 有点稀疏表示,因为有超过一百万 Unicode 字符,其中很少(几百个)是 十进制数字。下面的 Python 脚本会给你一个 C++ 可用于初始化的表 std::map<int, int> ;.如果角色是 在映射中,映射的元素就是它的值。

这是否足够取决于您的应用程序。 它有几个弱点:

  • 它需要额外的逻辑来识别两个连续的 数字在不同的字母表中。大概是一个序列 "1١" 应该被视为两个数字(1 和 1),而不是一个 (11). (因为所有十进制数字组都在 10 连续的代码,这将是相当容易的,一旦你知道了 数字,检查前面的数字字符是否在 同一套。)

  • 它会忽略非十进制数字,例如 ௰ 或 ൱(泰米尔十和 马来语一百)。没有那么多,而且他们是 也在 UnicodeData.txt 文件中,因此可能 手动找到它们并将它们添加到表中。我不知道 然而,我自己,当数字时它们如何与其他数字组合 已经组成。

  • 如果您要转换数字,您可能需要担心 方向。我不确定这是如何处理的(但有 Unicode 站点上的文档);一般来说,文字会出现 按照其自然顺序。对于阿拉伯语及相关 语言,当以自然顺序阅读时,低阶 数字首先出现:类似于 "١٢" (字面意思是 "12" , 但是因为书写是从右到左,所以数字会 出现在订单"21" ) 应该被解释为 12,而不是 21。除了我不确定是否有改变方向标记 存在与否。 (具体规则在 Unicode 站点上的文档;在 UnicodeData.txt 文件中, 第五个字段(索引 4)提供此信息。我 想想它是否不是"AN" ,你可以假设大端 欧洲使用的标准,但我不确定。)

为了展示这有多么简单,这里是 Python 脚本 解析数字值的 UnicodeData.txt 文件:

print('std::pair<int, int> initUnicodeMap[] = {')
for line in open("UnicodeData.txt"):
    fields = line.split(';')
    if fields[2] == 'Nd':
        print('    {{{:d}, {:d}}},'.format(int(fields[0], 16), int(fields[7])))
print('};')

如果您正在使用 Unicode 进行任何工作,那么这个文件就是一座金矿 用于生成各种有用的表格。

关于c++ - 将任何 Unicode 字符串转换为 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13780391/

相关文章:

c# - 通过等效的简化字母数字字符转换非 ascii 多文化字符

python - telnet 从 kannel 中的 fakesmsc 获取短信

java - "If"语句,常量相等

c++ - 在 fedora 27 中构建 glfw 时链接期间出错

c++ - 默认参数问题

qt - 如何在Qt中创建一侧向内弯曲而另一侧平坦的QPushbutton

qt - QListWidgetItem 项目相互重叠

c++ - Qt pro 文件条件库

python-3.x - 如何在Python 3中检查汉字是简体还是繁体?

c++ - 通过指向类成员的指针调用函数