用正则表达式解析一个字符串

时间:2014-06-11 15:22:48

标签: c++ regex

如果你想阅读这样的输入,最好的方法是什么:

(1,13) { (22,446) (200,66) (77,103) } 
(779,22) {  } // this is also possible, but always (X,X) in the beginning

我想使用正则表达式来做这件事。但是在解析具有多个数字的字符串时,关于reqexp的使用的信息很少。目前我尝试使用sscanf(来自c-library)类似的东西:

string data;
getline(in, data); // format: (X,X) { (Y,Y)* } 
stringstream ss(data);
string point, tmp;
ss >> point; // (X,X)
// (X,X) the reason for three is that they could be more than one digit.
sscanf(point.c_str(), "(%3d,%3d)", &midx, &midy); 

int x, y;
while(ss >> tmp) // { (Y,Y) ... (Y,Y) }
{
    if(tmp.size() == 5)
    {
        sscanf(tmp.c_str(), "(%3d,%3d)", &x, &y);
        cout << "X: " << x << " Y: " << y << endl;  
    }
}

问题是这不起作用,只要有多个数字,sscanf就不会读取数字。那么这是最好的方法,还是有一个更好的解决方案与regexp?我不想使用提升或类似的东西,因为这是学校作业的一部分。

2 个答案:

答案 0 :(得分:1)

假设你正在使用C ++ 11,你可以使用类似的东西:std::regex pattern(r"\((\d+),(\d+)\)\s*\{(\s*\(\d+,\d+\))+\s*\}")(免责声明:这还没有经过测试),然后像这样使用它:

std::smatch match;
while (ss >> tmp) {
   if (std::regex_match(tmp, match, pattern)) {
      // match[0] contains the first number as a string
      // match[1] contains the second number as a string
      // match[2] contains the list of points
   }
}

答案 1 :(得分:1)

也许以下代码符合您的要求:

#include <iostream>
#include <string>
#include <regex>

int main()
{
  std::smatch m;
  std::string str("(1,13) { (22,446) (200,66) (77,103) }");
  std::string regexstring = "(\\(\\s*\\d+\\s*,\\s*\\d+\\s*\\))\\s*(\\{)(\\s*\\(\\s*\\d+\\s*,\\s*\\d+\\s*\\)\\s*)*\\s*(\\})";
  if (std::regex_match(str, m, std::regex(regexstring))) {
    std::cout << "string literal matched" << std::endl;
    std::cout << "matches:" << std::endl;
    for (std::smatch::iterator it = m.begin(); it != m.end(); ++it) {
      std::cout << *it << std::endl;
    }
  }

  return 0;
}

输出:

enter image description here