【问题标题】:How to test a u32string for letters only (with locale)如何仅测试字母的 u32string(使用语言环境)
【发布时间】:2013-03-29 06:48:23
【问题描述】:

我正在编写一个编译器(用于我自己的编程语言),我希望允许用户使用 Unicode 字母类别中的任何字符来定义标识符(现代语言,如 Go 已经允许这样的语法)。 我已经阅读了很多关于 C++11 中字符编码的内容,并且根据我发现的所有信息,使用 utf32 编码会很好(在词法分析器中迭代速度很快,并且它比 utf8 有更好的支持在 C++ 中)。

在 C++ 中有isalpha 函数。我如何测试wchar32_t 是否是字母(在任何语言中被归类为“字母”的 Unicode 代码点)?

有可能吗?

【问题讨论】:

  • Unicode 标准包括在编程语言的“标识符”中应允许哪些字符的指南。 C++ 实际上被指定遵循这些准则,尽管在实际实现中支持仍然参差不齐。除了标识符和某些文字之外,您不必对字符进行分类,因为您几乎可以准确地指定每个标记。
  • 在哪里可以找到这些指导方针?是否有任何 C++ 函数可以检查特定字符是否可以在编程语言的“标识符”中使用(根据规范)?
  • 这个问题是关于测试有效的C++标识符字符还是有效的字母字符
  • 有效的字母字符,很抱歉造成混淆。 (我希望用户能够在我的语言中使用任何字母字符作为标识符的一部分),但第二个问题的答案也很好:)
  • 有关 Unicode 标识符的定义,请参见 UAX #31

标签: c++ unicode c++11 utf


【解决方案1】:

使用ICU 遍历字符串并检查是否满足适当的Unicode 属性。下面是一个用 C 语言检查 UTF-8 命令行参数是否为有效标识符的示例:

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <unicode/uchar.h>
#include <unicode/utf8.h>

int main(int argc, char **argv) {
  if (argc != 2) return EXIT_FAILURE;
  const char *const str = argv[1];
  int32_t off = 0;
  // U8_NEXT has a bug causing length < 0 to not work for characters in [U+0080, U+07FF]
  const size_t actual_len = strlen(str);
  if (actual_len > INT32_MAX) return EXIT_FAILURE;
  const int32_t len = actual_len;
  if (!len) return EXIT_FAILURE;
  UChar32 ch = -1;
  U8_NEXT(str, off, len, ch);
  if (ch < 0 || !u_isIDStart(ch)) return EXIT_FAILURE;
  while (off < len) {
    U8_NEXT(str, off, len, ch);
    if (ch < 0 || !u_isIDPart(ch)) return EXIT_FAILURE;
  }
}

请注意,这里的 ICU 使用 Java 定义,与UAX #31 中的定义略有不同。在实际应用程序中,您可能还希望之前标准化为 NFC。

【讨论】:

  • 谢谢!我会尝试并接受答案。如果您发现在编程语言编译器中使用这种编码有任何缺点,您能否再告诉我? (我说的是在编译器中使用 utf8 与 utf32 编码)。
  • @danilo2:我没有看到使用 UTF-8 的缺点。 UTF-32 只为您提供对单个代码点的恒定时间随机访问,但很少需要。
【解决方案2】:

ICU 项目中有一个isaplha。我认为你可以使用它。

【讨论】:

    猜你喜欢
    • 2018-01-16
    • 2020-05-01
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 2012-04-13
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多