1

我正在尝试从字符串中提取 n 个 3 元组(Si、Pi、Vi)。

该字符串至少包含一个这样的 3 元组。Pi 和 Vi 不是强制性的。

SomeTextxyz@S1((property(P1)val(V1))@S2((property(P2)val(V2))@S3
           |----------1-------------|----------2-------------|-- n 

所需的输出将是:

Si,Pi,Vi.

因此,对于字符串中出现 n 次,输出应如下所示:

[S1,P1,V1] [S2,P2,V2] ... [Sn-1,Pn-1,Vn-1] (without the brackets)

例子

输入字符串可能是这样的:

MyCarGarage@Mustang((property(PS)val(500))@Porsche((property(PS)val(425‌​)).

处理后的输出应为:

Mustang,PS,500 Porsche,PS,425

有没有一种有效的方法可以使用正则表达式(例如使用 C++ 和std::regex)提取这些 3 元组,它会是什么样子?

4

2 回答 2

3

@(.*?)\(\(property\((.*?)\)val\((.*?)\)\)应该做的伎俩。

http://regex101.com/r/bD1rY2上的示例

@                # Matches the @ symbol
(.*?)            # Captures everything until it encounters the next part (ungreedy wildcard)
\(\(property\(   # Matches the string "((property(" the backslashes escape the parenthesis
(.*?)            # Same as the one above
\)val\(          # Matches the string ")val(" 
(.*?)            # Same as the one above
\)\)             # Matches the string "))"

我不知道你应该如何在 C++ 中实现它,但这是简单的部分:)

于 2013-05-28T21:38:32.027 回答
1

http://ideone.com/S7UQpA

我使用 C<regex.h>而不是std::regex因为std::regex没有在 g++ 中实现(这是 IDEONE 使用的)。我使用的正则表达式:

"                        In C(++)? regexes are strings.
  @                      Literal match
  ([^(@]+)               As many non-@, non-( characters as possible.  This is group 1
  (                      Start another group (group 2)
    \\(\\(property\\(    Yet more literal matching
    ([^)]+)              As many non-) characters as possible.  Group 3.
    \\)val\\(            Literal again
    ([^)]+)              As many non-) characters as possible.  Group 4.
    \\)\\)               Literal parentheses
  )                      Close group 2
  ?                      Group 2 optional
"                        Close Regex

还有一些c++:

int getMatches(char* haystack, item** items){

首先,计算字符串的长度(我们稍后会用到)和@在字符串中找到的数量(最大匹配数)

    int l = -1, ats = 0;
    while (haystack[++l])
        if (haystack[l] == '@')
            ats++;

malloc 一个足够大的数组。

    *items = (item*) malloc(ats * sizeof(item));
    item* arr = *items;

制作一个正则表达式针来查找。REGEX 在#define其他地方是 d。

    regex_t needle;
    regcomp(&needle, REGEX, REG_ICASE|REG_EXTENDED);
    regmatch_t match[5];

ret将保存返回值(0 表示“找到匹配项”,但您可能希望在此处捕获其他错误)。 x将用于计算找到的匹配项。

    int ret;
    int x = -1;

循环匹配(如果找到匹配,ret 将为零)。

    while (!(ret = regexec(&needle, haystack, 5, match,0))){
        ++x;

从匹配1中获取名称

        int bufsize = match[1].rm_eo-match[1].rm_so + 1;
        arr[x].name = (char *) malloc(bufsize);
        strncpy(arr[x].name, &(haystack[match[1].rm_so]), bufsize - 1);
        arr[x].name[bufsize-1]=0x0;

检查以确保找到属性 (match[3]) 和值 (match[4])。

        if (!(match[3].rm_so > l || match[3].rm_so<0 || match[3].rm_eo > l || match[3].rm_so< 0
                || match[4].rm_so > l || match[4].rm_so<0 || match[4].rm_eo > l || match[4].rm_so< 0)){

从 match[3] 中获取属性。

            bufsize = match[3].rm_eo-match[3].rm_so + 1;
            arr[x].property = (char *) malloc(bufsize);
            strncpy(arr[x].property, &(haystack[match[3].rm_so]), bufsize - 1);
            arr[x].property[bufsize-1]=0x0;

从 match[4] 中获取值。

            bufsize = match[4].rm_eo-match[4].rm_so + 1;
            arr[x].value = (char *) malloc(bufsize);\
            strncpy(arr[x].value, &(haystack[match[4].rm_so]), bufsize - 1);
            arr[x].value[bufsize-1]=0x0;
        } else {

否则,将属性和值都设置为 NULL。

            arr[x].property = NULL;
            arr[x].value = NULL;
        }

将干草堆移动到匹配项之外并减少已知长度。

        haystack = &(haystack[match[0].rm_eo]);
        l -= match[0].rm_eo;
    }

返回匹配的数量。

    return x+1;
}

希望这可以帮助。虽然我现在想到你从来没有回答过一个至关重要的问题: 你尝试过什么?

于 2013-05-29T16:28:15.010 回答