C++ pcre2 UTF32的使用
我刚刚花了一些时间研究了pcre2接口,并且认为我已经掌握了它的大部分内容。我想支持UTF32,pcre2已经建立了支持和代码点宽度已设置为32 下面的代码是我将代码点宽度设置为8时得到的代码。 如何将其更改为与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
#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的数字。