【发布时间】:2021-03-28 12:03:16
【问题描述】:
在 Linux 下使用标准正则表达式库和 ANSI C 中的 PCRE 库进行了尝试:
需要在同一个字符串中多次捕获括号之间的内容,但我只能得到第一个或者它匹配整行(非贪婪匹配)。
src [] = "device=\"device 1\" device_name=\"the first device" address=\"192.168.1.10\" device=\"device 2\" device_name=\"the second device" address=\"192.168.1.12\" device=\"device 3\" device_name=\"the third device" address=\"192.168.1.13\"
所以我想要的结果是得到 3 个子字符串:
- 设备 1
- 设备 2
- 设备 3
int main(int argc, char *argv[]) {
pcre *re;
const char *error;
int erroffset;
int ovector[OVECCOUNT];
int rc, i;
char src [] = "device=\"device 1\" device_name=\"the first device" address=\"192.168.1.10\" device=\"device 2\" device_name=\"the second device" address=\"192.168.1.12\" device=\"device 3\" device_name=\"the third device" address=\"192.168.1.13\";
char pattern [] = ".+device=\"(.+(?R))\".+";
re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
if (re == NULL) {
printf("PCRE compilation failed at offset %d: %s\n", erroffset, error);
return 1;
}
rc = pcre_exec(re, NULL, src, strlen(src), 0, 0, ovector, OVECCOUNT);
if (rc < 0) {
if (rc == PCRE_ERROR_NOMATCH) printf("Sorry, no match ...\n");
else printf("Matching error %d/n", rc);
free(re);
return 1;
}
printf("\nOK, has matched ...\n\n");
for (i = 0; i < rc; i++) {
char *substring_start = src + ovector[2*i];
int substring_length = ovector[2*i+1] - ovector[2*i];
printf("%2d: %.*s\n", i, substring_length, substring_start);
}
free(re);
return 0;
}
网络上的正则表达式“测试者”可以设置全局标志,这似乎有效,但在 PCRE 中不可用。我能做什么?
理想情况下,我更喜欢使用标准的 regex.h 库,但如果需要,PCRE 也可以。
【问题讨论】:
-
我希望使用一个循环,其中第一次迭代从字符串的开头开始,随后的迭代在前一次迭代停止的地方继续。至少,该技术适用于(PCRE 和)来自 POSIX 的标准
regex.h。我很确定您可以找到正则表达式完成匹配的位置,只要从捕获的最后一个字符之后开始。可能还有另一种方法可以做到——我没有仔细研究。 -
另一种方法是使用标注pcre.org/current/doc/html/pcre2callout.html
device="\K.*?"(*SKIP)(?C1)此标注的返回值必须>0才能启动回溯。可以在callout函数中处理目标字符串。