2017-02-08 28 views
1

所以我有一个简单的回车符分隔的文件,上面写着:解析简单的语法,只有关键字和数抽取

room(800,400) 
place(desk, 5, 6) 
place(chair, 8, 5) 
place(bed, 6, 6) 
place(closet, 1, 4) 

我试图存储每个关键字(桌,椅,床和衣柜的发生)和相关的X,Y和存储的地方(不重要!)并提取room尺寸,并再次在一些地方保存。我的代码如下所示:

#include <iostream> 
#include <fstream> 
#include <string> 
using namepace std; 

void Keyword(ifstream & stream, string token) { 
    string line; 
    while (getline(stream, line)) { 
     if (line.find(token) != string::npos) { 
      cout << line << endl; 

      if(token == "room") { 
       //store the numbers and string to somewhere 
      } 

      if (token == "table") { 
       //store the numbers and string to somewhere 
      } 
     } 
    } 
    cout << token << " Not Found!" << endl; 
} 

int main() 
{ 

    // Shape Grammar Parser 
    ifstream infile("shape.dat"); 

    Keyword(infile, "room");  
    return 0; 
} 

我所试图做的是,当解析器看到place(chair, 8, 5)它存储在数据结构chair, 8, 5,或者当它看到房间它提取room, 800, 400

然而上述实施打破与此实现我只能提取的椅子,而不是相关的数字。如何做到这一点?我对正则表达式完全没有经验,所以我没有尝试它。

回答

1

一种方便,简单和不错的方式,std::regex_iterator

std::basic_regex<char> regex ("\\d+"); 
std::string string = "place(closet, 1, 4)"; 

std::regex_iterator<std::string::iterator> first (string.begin(), string.end(), regex); 
std::regex_iterator<std::string::iterator> last; 

while(first != last){ std::cout << first->str() << ' '; ++first; } 

输出

1 4


Inste我写给你的string的广告可以传递你的字符串。而已。

+1

辉煌。这是我一直在寻找的东西! –

2

这里的逻辑是颠倒的。相反,通过令牌名Keyword的(这需要一个更好的名字; parse_file可能是更具描述性的),调用Keyword只有一个istream&。让Keyword做找出其中存在令牌的工作:

while (get_line(stream, line)) { 
    std::string::size_type pos = line.find('('); 
    if (pos == std::string::npos) 
     throw file_read_failure(); // user-defined exception type 
    std::string token = line.substr(0, pos); 
    if (token == "room") 
     parse_room(line.substr(pos)); 
    else if (token == "table") 
     parse_table(line.substr(pos)); 
    // et cetera 
+0

为了让我理解正确,在使用子串分隔数字部分之后,我应该只查找逗号并提取2个数字?任何快速的方式来做到这一点? –

1

试试这个代码

void Keyword(ifstream & stream, string token) { 
    string line; 

    int dimension1; 
    int dimension2; 
    string item_in_room; 

    while (getline(stream, line,'(')) { 

     if (!line.compare("room")) 
     { 
      getline(stream, line,','); 
      dimension1 = atoi(line.c_str()); 

      getline(stream, line,')'); 
      dimension2 = atoi(line.c_str()); 

      cout << "It's a room, dimensions: " << dimension1 << " , " << dimension2 << endl; 
     } 

     if (!line.compare("place")) 
     { 
      getline(stream, item_in_room,','); 

      getline(stream, line,','); 
      dimension1 = atoi(line.c_str()); 

      getline(stream, line,')'); 
      dimension2 = atoi(line.c_str()); 

      cout << "It's a " << item_in_room << " dimensions: " << dimension1 << " , " << dimension2 << endl; 
     } 

     //read the rest of the line, just to get to a new new 
     getline(stream, line); 
    } 
    cout << token << " Not Found!" << endl; 
} 

它的工作原理,这里是输出:

这是一个房间,尺寸:800,400

这是一张桌子尺寸:5,6

这是一个椅子尺寸:8,5

这是一个床的尺寸:6,6

这是一个衣柜尺寸:1

房间未找到!

按任意键继续。 。 。