1

我有一些输入参数,例如:

参数1 =参数1 值&参数2 =参数2 值&参数3 =参数3 值...

这些参数用字符' & '链接,参数及其值用' = '链接。我想将它们解析成这样的键值映射:

[param1, param1Value], [param2, param2Value], [param3, param3Value],...

但是因为参数的值包含两个key-characters,这会破坏参数解析过程。

我被告知参数传递者,他们创建了这些参数格式以便于自定义,例如使用sprintf更改不同应用程序的参数值。所以很难说服他们将这些参数分隔在一个映射数组中。

我原本打算使用 yacc/lex,但是对于这样一个little-feature来说太复杂了。sscanf也可以解析类似正则表达式的文本,但是为我的参数列表构建一个类似正则表达式的字符串似乎并不容易。

有没有简单但可靠的方法可以在没有关键字符的情况下解析它们?

4

3 回答 3

6

您可以使用strtok在字符处对字符串进行标记'&',然后在处拆分“标记”'='以获取参数名称和值。

at 的拆分'='可以使用strtokas well (或者更确切地说strtok_r)或使用strchrand strncpy/strcpy or strndup/strdup来完成。

于 2012-04-13T07:10:11.323 回答
0

如果您保证该模式,您可以使用简单的解析函数。

如果保证键/值的最大长度,那么固定缓冲区 + 副本将是最简单的。否则,您可以先找到分隔符的位置,然后再找到该大小的 malloc 等。

作为一个简单的例子/概念,固定大小最大为 100,即:

#include <stdio.h>

int get_pair(char **p, char *key, char *val)
{
    int esc = 0;    /* escape level */
    char *cp = key; /* current target */

    *key = '\0';    /* if either is blank */
    *val = '\0';

    if (!*p || !**p)
        return 0;

    /* this could be done more elegant */
    while (**p) {
        if (**p == '=' && (esc & 1) == 0) {
            *cp = '\0'; /* terminate */
            cp = val;   /* change target */
            ++(*p);
            continue;
        } else if (**p == '&' && (esc & 1) == 0) {
            ++(*p);     /* skip & and break */
            break;
        }

        if (**p == '\\') {
            if((++esc & 1) == 0) /* if 2, 4, 6 ... \'s */
                *cp++ = **p;
        } else {
            esc = 0;
            *cp++ = **p;
        }
        ++(*p);
    }

    *cp = '\0';
    return 1;
}

int main(void)
{
    char *data = "ab=123&a\\=42&m\\\\ed\\=\\&do\\\\\\\\=mix";
    char key[100];
    char val[100];

    printf("Parse: %s\n", data);

    while (get_pair(&data, key, val))
        printf("key: %s\nval: %s\n\n", key, val);

    return 0;
}

输出:

Parse: ab=123&a\=42&m\\ed\=\&do\\\\=mix
key: ab
val: 123

key: a=42
val: 

key: m\ed=&do\\
val: mix
于 2012-04-13T08:57:15.363 回答
0

是的,我已经修复了它们:当 passer 给我参数时,它们应该\用来转义=and &,但\本身不需要转义。当我提取这些参数时,我只是 \&&, 和\='=' 替换了。如果实际值是\\=,只需将其编码为\\\=。我不需要分析\角色,只需将它们留在原处即可。

于 2012-05-08T15:14:47.517 回答