2017-08-10 2 views
1

Je veux résoudre les macros dans une même ligne. Je définir des macros dans une carte:Résoudre plusieurs macros dans une même ligne avec std :: regex_search

map<string, string> collection; 
collection["ComputerName"] = "Train-Alpha"; 
collection["State"] = "Unloaded"; 

La notation des macros est $ (MacroName) de sorte que la ligne d'entrée ressemble à:

string line = "Running on $(ComputerName) while $(State)"; 

Et j'utilise cette expression régulière:

regex expression("\\$\\(([^}]+)\\)"); 

Mais mon code ci-dessous considère le sous-motif le plus grand plutôt que le plus petit:

#include <iostream> 
#include <regex> 
#include <map> 
#include <boost/algorithm/string.hpp> 

using namespace std; 

void main() 
{ 
    string line = "Running on $(StationName) while $(State)"; 
    map<string, string> collection; 
    collection["Station"] = "Train-Alpha"; 
    collection["State"] = "unloaded"; 
    regex pattern("\\($\\([^}]+\\))"); 
    smatch match; 

    while (regex_search(line, match, pattern)) 
    { 
     auto variableName = match[1].str(); 
     auto it = collection.find(variableName); 
     if (it != end(collection)) 
     { 
      auto keyword = "$(" + variableName + ")"; 
      auto value = it->second; 
      boost::replace_all(line, keyword, value); 
     } 
     else 
     { 
      break; 
     } 
    } 
    cout << line << endl; 
} 
+1

Si les noms des macros peuvent être imbriqué, une expression régulière est insuffisante: est la ligne $ (has-a-$ (macro-imbriquée)) "'. –

Répondre

1

Vous avez des erreurs dans votre code:

  1. La première valeur mappée doit être modifiée:

    collection["Station"] = "Train-Alpha"; 
    

    par

    collection["StationName"] = "Train-Alpha"; 
    
  2. Le regex doit également être modifié:

    regex pattern("\\($\\([^}]+\\))"); 
    

    par

    regex pattern("\\$\\(([^)]+)\\)"); 
    

    Vous pouvez également utiliser un Raw string literal pour éviter d'échapper aux barres obliques inverses (ou tout autre caractère):

    regex pattern(R"(\$\(([^)]+)\))"); 
    

See a slightly modified working version on Ideone.