Dường như POSIX Regex hoạt động đúng với ngôn ngữ UTF-8. Tôi vừa viết một bài kiểm tra đơn giản (xem bên dưới) và sử dụng nó để kết hợp chuỗi ký tự với một ký tự không gian chống lại regex "[[:alpha:]]"
(ví dụ). Và mọi thứ hoạt động tốt.
Lưu ý: Điều chính bạn phải nhớ - chức năng regex có liên quan đến miền địa phương. Vì vậy, bạn phải gọi setlocale()
trước đó.
#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;
}
Cách sử dụng Ví dụ:
$ 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: 'ф'
$
Chiều dài của kết quả phù hợp là hai byte vì chữ Cyrillic trong UTF-8 mất rất nhiều.
Nguồn
2012-01-04 14:38:42
Không phải là tôi biết, nhưng thư viện kế hoạch 9 regex là; một cổng unix là tại http://swtch.com/plan9port/unix/ dưới 'libregexp9' – Dave