【问题标题】:Global matching using PCRE使用 PCRE 进行全局匹配
【发布时间】:2022-01-11 16:19:58
【问题描述】:

我尝试使用 PCRE 匹配逗号分隔的键值对。文本如下所示:

"key1": "value1", "key2": "value2"

测试的模式是:

/(\s*)(,?)"([a-zA-Z0-9]+?)":(\s*)"([a-zA-Z0-9]+?)"/gm

正则表达式可以测试here:

它可以在这个测试页面中工作,但是使用这个 C 代码它只显示第一个匹配的组。

pcre *re;
pcre_extra *sd;
const char *error;
int rc, erroroffset, i;
int ovector[OVECCOUNT];
re = pcre_compile(pattern, 0, &error, &erroroffset, NULL);
sd = pcre_study(
    re,             /* result of pcre_compile() */
    0,              /* no options */
    &error);        /* set to NULL or points to a message */
rc = pcre_exec(   /* see below for details of pcre_exec() options */
    re, sd, json, 7, 0, 0, ovector, 30);
pcre_free_study(sd);
printf("Match succeeded at offset %d\n", ovector[0]);
for (i = 0; i < rc; i++) {
    char *substring_start = json + ovector[2*i];
    int substring_length = ovector[2*i+1] - ovector[2*i];
    printf("%2d: '%.*s'\n", i, substring_length, substring_start);
}

结果是

Match succeeded at offset 1
 0: '"key1": "value1"'
 1: ''
 2: ''
 3: 'key1'
 4: ' '
 5: 'value1'

但我需要所有匹配的组,与

'key2'
'value2'

【问题讨论】:

  • 您没有在问题中显示正则表达式 - 异地链接可能是有用的辅助信息,但不是问题的一部分。您还需要阅读如何创建 MCVE(Minimal, Complete, Verifiable Example — 或 MRE 或 SO 现在使用的任何名称)或 SSCCE(Short, Self-Contained, Correct Example) — 以不同的名称创建相同的想法。您尚未显示输入数据,但我们不必猜测。
  • 更新很有帮助——谢谢。您应该考虑在正则表达式的冒号前添加\s*; JSON 允许有空格。

标签: c regex pcre


【解决方案1】:

pcre_exec() 的一次执行将捕获一个键值对。您必须重复 pcre_exec() 才能获得额外的键值对。显然,在第二次迭代中,您需要从字符串中的不同位置开始——最后一个匹配字符的偏移量为ovector[1],因此您可以捕获并使用:

size_t offset = 0;

while ((rc = pcre_exec(…, json + offset, …)) == 0)
{
    …
    offset += ovector[1];
}

你也可以调查pcre_dfa_exec()

我想知道为什么您将(可选)前导空格和逗号作为单独的项目捕获——这些信息有用吗?当然,这取决于您的要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    相关资源
    最近更新 更多