pcre2 UTF32用法

时间:2015-05-03 21:31:28

标签: c++ unicode pcre utf

我刚刚花了一些时间搞清楚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标题中找不到任何内容来表示支持。 我猜subjectlen不再仅仅是strlen

最后,我将这个例子放在一起,通过了一些文档和标题,还有什么我应该做的/值得了解。

3 个答案:

答案 0 :(得分:0)

我最后离开了pcre2,在评估了RE2,PCRE2和ICU后,我选择了ICU。它的unicode支持(从我迄今为止看到的)比其他两个更完整。它还提供了一个非常干净的API和许多用于操作的实用程序。重要的是,像PCRE2一样,它提供了一个perl风格的正则表达式引擎,它开箱即用,非常适用于unicode。

答案 1 :(得分:0)

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

将c_str()转换为PCRE2_SPTR并不会使字符串为utf32。

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

答案 2 :(得分:0)

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

std::string的基本单位是char,通常为8位,支持UTF-8(根据实现/系统可能会有所不同)。因此,在此类系统中处理UTF-32时,您无法使用std::string("some string")和此类代码。

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

在GNU / Linux中,您可以使用wchar_t,即std::wstring,它是32位且支持UTF-32。在Windows wchar_t中是16位(使用UTF-16)。

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

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