C ++:正则表达式:返回完整的字符串,而不是匹配的组

时间:2014-06-06 12:57:42

标签: c++ regex regex-group

对于那些要求,{0}允许选择sResult字符串中由|分隔的任何一个块。 0是第一个块

它需要是动态的,以便将来扩展,因为该数字可由用户配置

所以我正在使用正则表达式来提取字符串的1个部分,但是当它匹配时,结果返回不是预期的结果。

    std::string sResult = "MATCH_ME|BUT|NOT|ANYTHNG|ELSE";
    std::regex pattern("^(?:[^|]+[|]){0}([^|;]+)");
    std::smatch regMatch;

    std::regex_search(sResult, regMatch, pattern);
    if(regMatch[1].matched)
    {
      for( int i = 0; i < regMatch.size(); i++)
      {
           //SUBMATCH 0 = "MATCH_ME|BUT|NOT|ANYTHNG|ELSE"
           //SUBMATCH 1 = "BUT|NOT|ANYTHNG|ELSE"
        std::ssub_match sm = regMatch[i];
        bValid = strcmp(regMatch[i].str().c_str(), pzPoint->_ptrTarget->_pzTag->szOPCItem);
      }
    }

出于某种原因,我无法弄清楚代码让我只回到MATCH_ME,所以我可以将它与C ++方面的预期结果列表进行比较。

任何人对我在哪里出错都有任何想法。

3 个答案:

答案 0 :(得分:1)

以下代码示例演示了如何执行以下操作 - 编译它,然后使用单个数字参数调用它以提取输入的元素:

#include <iostream>
#include <cstring>
#include <regex>

int main(int argc, char *argv[]) {

    char pat[100];
    if (argc > 1) {
      sprintf(pat, "^(?:[^|]+[|]){%s}([^|;]+)", argv[1]);
      std::string sResult = "MATCH_ME|BUT|NOT|ANYTHNG|ELSE";
      std::regex pattern(pat);
      std::smatch regMatch;

      std::regex_search(sResult, regMatch, pattern);
      if(regMatch[1].matched)
      {
        std::ssub_match sm = regMatch[1];
        std::cout << "The match is " << sm << std::endl;
//bValid = strcmp(regMatch[i].str().c_str(), pzPoint->_ptrTarget->_pzTag->szOPCItem);
      }
    }
    return 0;
}

创建名为match的可执行文件,然后可以执行

>> match 2
The match is NOT

这就是你想要的。

事实证明,正则表达式运行得很好 - 虽然作为优先选择,我会在第一部分使用\|而不是[|]

答案 1 :(得分:1)

您似乎正在使用正则表达式来表达他们尚未设计的内容。您应首先在分隔符|处拆分字符串,并在结果标记上应用正则表达式,如果要检查它们的有效性。

顺便说一下:std::regex中的libstdc++实施似乎是错误的。我刚做了一些测试,发现即使包含转义管道字符(如\\|)的简单模式也无法编译抛出std::regex_error而错误消息中没有更多信息(GCC 4.8.1)。

答案 2 :(得分:0)

事实证明问题是在C端提取匹配,它必须更直接地完成,下面的代码能让我完全得到我想要的字符串,以便我以后可以使用它。

std::string sResult = "MATCH_ME|BUT|NOT|ANYTHNG|ELSE";
std::regex pattern("^(?:[^|]+[|]){0}([^|;]+)");
std::smatch regMatch;

std::regex_search(sResult, regMatch, pattern);
if(regMatch[1].matched)
{
   std::string theMatchedPortion = regMatch[1];
   //the issue was not with the regex but in how I was retrieving the results.
   //theMatchedPortion now equals "MATCH_ME" and by changing the number associated 
        with it I can navigate through the string
}