c++ - 如何解析多行的字符串对?

标签 c++ string parsing

我想解析如下内容:

tag = value
tag2 = value2
tag3 = value3

放宽了允许值跨越多行并忽略下一个标签的注释。通过不以注释标识符“#”开头并从新行开始来标识标签。所以这个:

tag = value
  value continuation
tag2 = value2
  value continuation2
# comment for tag3
tag3 = value3

应该解析映射:

tag : "value\nvalue continuation"
tag2 : "value2\nvalue continuation2"
tag3 : "value3"

我怎样才能以干净的方式实现这一点?我当前用于解析单行对的代码看起来像这样:

while( std::getline( istr, line ) )
{
  ++lineCount;
  if( line[0] == '#' )
    currentComment.push_back( line );
  else if( isspace( line[0]) || line[0] == '\0' )
    currentComment.clear( );
  else
  {
    auto tag = Utils::string::splitString( line, '=' );
    if( tag.size() != 2 || line[line.size() - 1] == '=')
    {
      std::cerr << "Wrong tag syntax in line #" << lineCount << std::endl;
      return nullptr;
    }
    tagLines.push_back( line );
    currentComment.clear( );
  } 
}

请注意,我不要求将结果存储在当前使用的容器类型中。我可以切换到任何更适合的东西,除非我得到一组(注释、标记名、值)。

最佳答案

一般regexs add complexity to your code ,但在这种情况下,正则表达式似乎是最好的解决方案。像这样的正则表达式将捕获你的对的第一部分和第二部分:

(?:\s*#.*\n)*(\w+)\s*=\s*((?:[^#=\n]+(?:\n|$))+)

[ Live example ]

In order to use a regex_iterator on an istream you'll need to either slurp the stream or use boost::regex_iterator with the boost::match_partial flag.假设 istream 已被输入 string input。此代码将提取对:

const regex re("(?:\\s*#.*\\n)*(\\w+)\\s*=\\s*((?:[^#=\\n]+(\\n|$))+)");

for (sregex_iterator i(input.cbegin(), input.cend(), re); i != sregex_iterator(); ++i) {
    const string tag = i->operator[](1);
    const string value = i->operator[](2);

    cout << tag << ':' << value << endl;
}

[ Live example ]

这显然超出了原题中的要求;解析标签和值,而不是仅仅抓取行。这里有相当多的 C++ 新功能,所以如果有任何问题,请在下面评论。

关于c++ - 如何解析多行的字符串对?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31808350/

相关文章:

c++ - 错误 : ‘split’ was not declared in this scope

c++ - 如何在 CLion 中同时运行多个调试器?

c++ - 应用程序崩溃,因为 dll 不兼容

python - 如何在Python中解析带有括号的电子邮件FROM header ?

c# - 确定字符串中是否包含 base64 字符串

c++ - 按地址访问结构中的元素

c 字符串数组中的指针

python - 在 Python 中反转字符串

android - Jsoup html代码解析

javascript - 把句子串分成子串=<最长单个词的长度