pcre2 UTF32 用法

pcre2 UTF32 usage

我刚刚花了一些时间弄清楚 pcre2 接口,并认为我已经掌握了大部分内容。我想支持 UTF32,pcre2 已经内置支持,代码点宽度已设置为 32。

下面的代码是我将代码点宽度设置为 8 的代码。 我如何更改它以使用 UTF32?

#include "gtest/gtest.h"
#include <pcre2.h>

TEST(PCRE2, example) {
//iterate over all matches in a string
  PCRE2_SPTR subject = (PCRE2_SPTR) string("this is it").c_str();
  PCRE2_SPTR pattern = (PCRE2_SPTR) string("([a-z]+)|\s").c_str();
  int errorcode;
  PCRE2_SIZE erroroffset;
  pcre2_code *re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, PCRE2_ANCHORED | PCRE2_UTF, &errorcode,
                                 &erroroffset, NULL);
  if (re) {
    uint32_t groupcount = 0;
    pcre2_pattern_info(re, PCRE2_INFO_BACKREFMAX, &groupcount);
    pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL);
    uint32_t options_exec = PCRE2_NOTEMPTY;
    PCRE2_SIZE subjectlen = strlen((const char *) subject);
    errorcode = pcre2_match(re, subject, subjectlen, 0, options_exec, match_data, NULL);
    while (errorcode >= 0) {
      PCRE2_UCHAR *result;
      PCRE2_SIZE resultlen;
      for (int i = 0; i <= groupcount; i++) {
        pcre2_substring_get_bynumber(match_data, i, &result, &resultlen);
        printf("Matched:%.*s\n", (int) resultlen, (const char *) result);
        pcre2_substring_free(result);
      }
      // Advance through subject
      PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
      errorcode = pcre2_match(re, subject, subjectlen, ovector[1], options_exec, match_data, NULL);
    }
    pcre2_match_data_free(match_data);
    pcre2_code_free(re);
  } else {
    // Syntax error in the regular expression at erroroffset
    PCRE2_UCHAR error[256];
    pcre2_get_error_message(errorcode, error, sizeof(error));
    printf("PCRE2 compilation failed at offset %d: %s\n", (int) erroroffset, (char *) error);
  }

大概 subjectpattern 需要以某种方式转换并且 result 是同一类型?我在 pcre2 header 中找不到任何东西来表明对此的支持。 我想 subjectlen 将不再是简单的 strlen.

最后,我通过一些文档和 header 将这个示例放在一起,还有什么我应该 doing/worth 知道的。

我最后留下了pcre2,综合评估了RE2、PCRE2和ICU后,我选择了ICU。它的 unicode 支持(据我目前所见)比其他两个更完整。它还提供了一个非常干净的 API 和许多用于操作的实用程序。重要的是,PCRE2 提供了一个 perl 风格的正则表达式引擎,开箱即用,可以很好地与 unicode 配合使用。

如果您正确设置代码宽度,这可能是问题所在: (PCRE2_SPTR) string("this is it").c_str();

将 c_str() 转换为 PCRE2_SPTR 不会生成字符串 utf32。

如果您不确定设置正确的代码宽度(我没有在您的源代码中看到它),您可以通过向所有内容添加 _32 后缀来强制使用 32 位,例如pcre2_compile_32.

这取决于您要使用的字符类型以及您要定位的系统。

std::string的基本单位是char,一般为8位,支持UTF-8(因implementation/system而异)。因此在此类系统中处理 UTF-32 时不能使用 std::string("some string") 和此类代码。

PCRE2_CODE_UNIT_WIDTH 必须与您要使用的基本字符单元的位大小相匹配。对于 8 位 char 它应该定义为 8,对于 16 位 char 它应该定义为 16 等等...

在 GNU/Linux 中,您可以使用 wchar_tstd::wstring,它是 32 位的并且支持 UTF-32。在 windows wchar_t 中是 16 位(使用 UTF-16)。

>=C++11 中,您可以使用 char32_tstd::u32string,它至少是 32 位(您必须确保它在您的目标系统中恰好是 32 位)

我有一个 wrapper 用于 C++ 中的 PCRE2,其中包含一些关于如何处理 UTF-16 和 UTF-32 模式的示例(在 src 目录中)。