[英]Does POSIX regex.h provide unicode or basically non-ascii characters?
嗨,我正在使用标准正则表达式库(regcomp,regexec ..)。 但是现在按需要我应该为我的正则表达式代码添加unicode支持。
标准正则表达式库是否提供unicode或基本上非ascii字符? 我在网上研究,并没有想到。
我的项目是资源批评者因此我不想使用大型库(ICU和Boost.Regex)。
任何帮助,将不胜感激..
看起来POSIX Regex正常使用UTF-8语言环境。 我刚刚编写了一个简单的测试(见下文)并用它来匹配字符串与正则字符"[[:alpha:]]"
(例如)的西里尔字符。 一切正常。
注意:您必须记住的主要内容 - 正则表达式函数与语言环境相关。 所以你必须先调用setlocale()
。
#include <sys/types.h>
#include <string.h>
#include <regex.h>
#include <stdio.h>
#include <locale.h>
int main(int argc, char** argv) {
int ret;
regex_t reg;
regmatch_t matches[10];
if (argc != 3) {
fprintf(stderr, "Usage: %s regex string\n", argv[0]);
return 1;
}
setlocale(LC_ALL, ""); /* Use system locale instead of default "C" */
if ((ret = regcomp(®, argv[1], 0)) != 0) {
char buf[256];
regerror(ret, ®, buf, sizeof(buf));
fprintf(stderr, "regcomp() error (%d): %s\n", ret, buf);
return 1;
}
if ((ret = regexec(®, argv[2], 10, matches, 0)) == 0) {
int i;
char buf[256];
int size;
for (i = 0; i < sizeof(matches) / sizeof(regmatch_t); i++) {
if (matches[i].rm_so == -1) break;
size = matches[i].rm_eo - matches[i].rm_so;
if (size >= sizeof(buf)) {
fprintf(stderr, "match (%d-%d) is too long (%d)\n",
matches[i].rm_so, matches[i].rm_eo, size);
continue;
}
buf[size] = '\0';
printf("%d: %d-%d: '%s'\n", i, matches[i].rm_so, matches[i].rm_eo,
strncpy(buf, argv[2] + matches[i].rm_so, size));
}
}
return 0;
}
用法示例:
$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
... (skip)
LC_ALL=
$ ./reg '[[:alpha:]]' ' 359 фыва'
0: 5-7: 'ф'
$
匹配结果的长度是两个字节,因为UTF-8中的西里尔字母需要很多。
基本上,POSIX正则表达式不支持Unicode。 您可以尝试在Unicode字符上使用它们,但是可能存在具有多种编码的字形以及Unicode感知库为您处理的其他此类问题。
从标准IEEE Std 1003.1-2008 :
匹配应基于用于编码字符的位模式,而不是基于字符的图形表示。 这意味着如果字符集包含两个或多个图形符号的编码,或者如果搜索的字符串包含以多个代码集编码的文本,则不会尝试搜索编码符号的任何其他表示。 如果需要,用户可以指定包含所需图形符号的所有变体的等价类。
也许libpcre适合你? 它比POSIX正则表达稍重,但我认为它比ICU或Boost轻。
如果你的意思是“标准”,即来自C ++ 11的std::regex
,那么你需要做的就是切换到std::wregex
(当然还有std::wstring
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.