2017-02-08 36 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

房間未找到!

按任意鍵繼續。 。 。