我刚刚花了一些时间搞清楚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);
}
据推测,subject
和pattern
需要以某种方式转换,result
属于同一类型?我在pcre2标题中找不到任何内容来表示支持。
我猜subjectlen
不再仅仅是strlen
。
最后,我将这个例子放在一起,通过了一些文档和标题,还有什么我应该做的/值得了解。
答案 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_t
即std::u32string
(您必须确保它在您的目标系统中完全是32位)
我在C ++中有一个wrapper PCRE2,它包含一些关于如何处理UTF-16和UTF-32模式的例子(在src目录中)。