扩展'isalnum'以识别 UTF-8 变音符号

Extending 'isalnum' to recognize UTF-8 umlaut

本文关键字:音符 符号 UTF-8 isalnum 扩展 识别      更新时间:2023-10-16

我编写了一个扩展isalnum的函数来识别UTF-8编码的变音符

有没有更优雅的方法来解决这个问题?

代码如下:

bool isalnumlaut(const char character) {
    int cr = (int) (unsigned char) character;
    if (isalnum(character)
            || cr == 195 // UTF-8
            || cr == 132 // Ä
            || cr == 164 // ä
            || cr == 150 // Ö
            || cr == 182 // ö
            || cr == 156 // Ü
            || cr == 188 // ü
            || cr == 159 // ß
    ) {
        return true;
    } else {
        return false;
    }
}
编辑:

我现在测试了我的解决方案几次,它似乎为我的目的做了工作。有强烈的反对意见吗?

你的代码没有做到你所声称的。

Ä的utf-8表示为两个字节- 0xC3,0x84。值大于0x7F的单个字节在utf-8中是没有意义的。


一般性建议:

  • Unicode较大。考虑使用已经处理过您所看到的问题的库,例如ICU。

  • 函数在单个代码单元代码点上操作通常没有意义。让函数在代码点范围或单个字形上操作更有意义(参见此处查看这些术语的定义)。

  • 对于像通用字符集这样大的字符集,您的字母数字概念可能未被充分指定;是否要将西里尔字母中的字符视为字母数字?Unicode对字母顺序的概念可能与你的不一致——特别是如果你没有考虑过的话。

我不是100%确定,但<locale>中的c++ std::isalnum几乎肯定可以识别特定于区域设置的附加字符:http://www.cplusplus.com/reference/std/locale/isalnum/

使用您定义的接口是不可能的,因为UTF-8是一个多字节编码;单个字符需要多个char to表示它。(我有代码来确定UTF-8是否是一个是库中指定字符集的成员,但是字符由一对迭代器指定,而不是单个char)