【问题标题】:C++11 regex (extract pairs)C++11 正则表达式(提取对)
【发布时间】:2013-06-06 12:54:31
【问题描述】:

如何使用新的 C++ 11 正则表达式库从文档中提取 field = value 对?

文档示例(将其视为 std::string):

Caption = "calc.exe";命令行 = "\"C:\Windows\system32\calc.exe\" "; CreationClassName = "Win32_Process";创建日期 = "20130606162432.173628+240"; CSCreationClassName = "Win32_ComputerSystem" 句柄 = "13484"; HandleCount = 93;

作为输出,我需要获取地图:

{"Caption", "calc.exe"}
{"CommandLine", "\"C:\\Windows\\system32\\calc.exe\" "}
{"CreationClassName", "Win32_Process"}
{"CreationDate", "20130606162432.173628+240"}
{"CSCreationClassName", "Win32_ComputerSystem"}
{"Handle", "13484"}
{"HandleCount", "93"}

我想要的代码可能是这样的:

Todo

【问题讨论】:

  • 你不能用分号标记,然后用空格标记吗?
  • @VoronoiPotato 你能提供一些示例代码吗?
  • 出于好奇,您使用的是哪个编译器? AFAIKnew, <regex> 在 gcc 中被破坏
  • 对不起,我使用 Visual Studio 2012 Express
  • "quoted strings" 可以包含; 吗? (示例中未知)可以"quoted strings have \" escaped quotes" 吗? (是的)在您的示例中,Handle 之前缺少的; 是故意丢失还是 tpyo?这些strings 是机器生成的,还是人工输入的?格式有多严格?出现错误需要做什么?

标签: c++ regex parsing c++11


【解决方案1】:

我做了这个工作,但它真的只适用于带有libc++的clang++ 3.2(即,在Mac上):

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

using namespace std;

int main(int, char**) {
  string input;
  getline(cin, input, '\0');
  cout << input;

  regex rx { string { R"---((\w+) *= *([^;]*))---" } };
  for( sregex_iterator E, i { input.begin(), input.end(), rx }; i != E; ++i ) {
    cout << "match: (" << (*i)[1].str() << ")(" << (*i)[2].str() << ")" << endl;
  }

  return 0;
}

【讨论】:

  • 感谢您的帮助!你做得很好!我会赏金你;)
【解决方案2】:

创建一个正则表达式,该表达式匹配一个文本字段,后跟一个“=”符号,后跟一个文本字段,后跟一个“;”。创建一个regex_iterator 对象,将该正则表达式应用于目标文本。迭代直到完成。

【讨论】:

    【解决方案3】:

    我无法让 gcc/libstdc++ 正则表达式工作。我能做的最好的似乎是解决你的问题是这样的:

      #include <iostream>
      #include <string>
    
      using namespace std;
    
      class unquot {
        string where;
        char what, quote;
      public:
        unquot(char _what = '"', char _quote = '\\') : what(_what), quote(_quote) {}
        string str() { return where; }
    
        friend istream& operator>>(istream& i, unquot& w) {
          w.where = string();
    
          char c = i.get();
          if( !i )
            return i;
    
          if( c != w.what ) {
            i.setstate(ios::failbit);
            i.putback(c);
            return i;
          }
    
          bool quoted = false;
          for( c = i.get(); i; c = i.get() ) {
            if( quoted ) {
              w.where.push_back(c);
              quoted = false;
            } else if( c == w.quote ) {
              quoted = true;
            } else if( c == w.what ) {
              break;
            } else {
              w.where.push_back(c);
            }
          }
    
          return i;
        }
      };
    
      class until {
        string where;
        char what, quote;
      public:
        until(char _what = '"', char _quote = '\\') : what(_what), quote(_quote) {}
        string str() { return where; }
    
        friend istream& operator>>(istream& i, until& w) {
          w.where = string();
    
          char c = i.get();
          if( !i )
            return i;
    
          if( c != w.what ) {
            i.setstate(ios::failbit);
            i.putback(c);
            return i;
          }
    
          w.where.push_back(c);
    
          bool quoted = false;
          for( c = i.get(); i; c = i.get() ) {
            w.where.push_back(c);
            if( quoted ) {
              quoted = false;
            } else if( c == w.quote ) {
              quoted = true;
            } else if( c == w.what ) {
              break;
            }
          }
    
          return i;
        }
      };
    
      class word {
        string where;
      public:
        word() {}
        string str() { return where; }
    
        friend istream& operator>>(istream& i, word& w) {
          bool before = true, during = false;
          w.where = string();
    
          for( char c = i.get(); i; c = i.get() ) {
            bool wordchar = isalnum(c) || (c == '_');
            bool spacechar = isspace(c);
            bool otherchar = !wordchar && !spacechar;
    
            if( before ) {
              if( wordchar ) {
                swap(before, during);
                w.where.push_back(c);
              } else if( otherchar ) {
                i.setstate(ios::failbit);
                i.putback(c);
                break;
              }
            } else if( during ) {
              if( wordchar ) {
                w.where.push_back(c);
              } else if( otherchar ) {
                i.putback(c);
                break;
              } else {
                during = false;
              }
            } else {
              if( !spacechar ) {
                i.putback(c);
                break;
              }
            }
          }
          return i;
        }
      };
    
      class skip {
        char which;
      public:
        skip(char _which) : which(_which) {}
        friend istream& operator>>(istream& i, skip& s) {
          bool before = true;
          for( char c = i.get(); i; c = i.get() ) {
            if( c == s.which ) {
              before = false;
            } else if( !isspace(c) ) {
              i.putback(c);
              if( before )
                i.setstate(ios::failbit);
              break;
            }
          }
          return i;
        }
      };
    
    
    
      int main ()
      {
        word w;
        skip eq { '=' };
        unquot q;
        skip semi { ';' };
        while( cin >> w >> eq >> q >> semi ) {
          cout << w.str() << " {" << q.str() << "}" << endl;
        }
    
        return 0;
      }
    

    您可以使用“直到 q;”而不是“取消引用 q;”如果你想保留引号......

    【讨论】:

    • 不客气。我使用 g++ 和 clang++ 以及 libstdc++ 进行了更多测试。我在这里拥有的 libstdc++ 版本似乎缺少正则表达式函数 defs。我想它可以在 MacOSX 上与 libc++ 一起使用,但我没有时间测试它。祝你好运!
    猜你喜欢
    • 2015-09-04
    • 2016-09-17
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 2015-06-27
    相关资源
    最近更新 更多