C++ pcre2 UTF32的使用

C++ pcre2 UTF32的使用,c++,unicode,pcre,utf,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接口,并且认为我已经掌握了它的大部分内容。我想支持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);
  }
#包括“gtest/gtest.h”
#包括
测试(PCRE2,示例){
//迭代字符串中的所有匹配项
PCRE2_SPTR subject=(PCRE2_SPTR)字符串(“就是它”).c_str();
PCRE2_SPTR模式=(PCRE2_SPTR)字符串(([a-z]+)|\\s”).c_str();
国际误码;
PCRE2_尺寸误差补偿;
pcre2_代码*re=pcre2_编译(模式、pcre2_零终止、pcre2_锚定、pcre2_UTF和错误代码,
&erroroffset,NULL);
如果(re){
uint32\u t groupcount=0;
pcre2_模式_信息(re、pcre2_信息_BACKREFMAX和groupcount);
pcre2_match_data*match_data=pcre2_match_data_create_from_pattern(re,NULL);
uint32\u t options\u exec=PCRE2\u NOTEMPTY;
PCRE2_SIZE subject len=strlen((常量字符*)subject);
errorcode=pcre2\u匹配(re,subject,subjectlen,0,options\u exec,match\u data,NULL);
而(错误代码>=0){
PCRE2_UCHAR*结果;
PCRE2_尺寸结果;

对于(int i=0;i我最终离开了pcre2,在评估了RE2、pcre2和ICU之后,我选择了ICU。它的unicode支持(从我目前看到的情况来看)它比其他两个更完整。它还提供了一个非常干净的API和许多用于操作的实用程序。重要的是,像PCRE2一样,它提供了一个perl风格的正则表达式引擎,它在unicode上可以立即运行。

如果您正确设置代码宽度,这可能是个问题:
(PCRE2_SPTR)字符串(“就是它”).c_str();

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


如果您不确定设置正确的代码宽度(我在您的密码中没有看到),您可以通过在所有内容中添加32个后缀来强制设置32位,例如
pcre2\u compile\u 32

,这取决于您要使用的字符类型和目标系统

std::string
的基本单位是
char
,通常为8位,支持UTF-8(根据实现/系统的不同而有所不同)。因此,在此类系统中处理UTF-32时,不能使用
std::string(“某些字符串”)
和此类代码

PCRE2\u code\u UNIT\u WIDTH
必须与要使用的基本字符单元的位大小相匹配。对于8位
char
应将其定义为8,对于16位
char
应将其定义为16等

在GNU/Linux中,您可以使用
wchar\u t
std::wstring
,它是32位且支持UTF-32。在windows中
wchar\u t
是16位(带有UTF-16)

=C++11
中,您可以使用
char32\u t
std::u32string
,它至少是32位(您必须确保它在目标系统中正好是32位)


我在C++中有一个pCRE2,它包含了一些关于如何处理UTF-16和UTF-32模式的例子。

可以通过UpEX引擎显式地改变Unicode模式,通过指令的“代码> >(*UTF32)< /Code >(或<代码>(*UTF16)< /Code >或<代码>(*UTF8)< /代码>),通过ReX引擎看到输入字符串。在模式的一开始(在模式本身内部)。pcre2文档中确实没有关于这些指令的内容(但您应该进行测试)。但是
(*UTF)
似乎是为了设置目标字符串的相关模式而设计的。(并且是在pcre2文档中:)您所说的Perl风格?
(*SKIP)
(回溯控制),
(?(DEFINE))
(子模式)、
\g
(递归)、
(?(?=)|)
(条件)等等都不受支持。如果这对你来说没问题,那么一切都很好,但你应该知道巨大的功能差异。嗯,对我来说最重要的是(消极的)前瞻断言,ICU确实有。所以我可以做
(?!1234)\d{4}
,为我找到3个不是1234的数字。