【问题标题】:Elegant solution for string parsing优雅的字符串解析解决方案
【发布时间】:2023-03-19 00:03:01
【问题描述】:

所以我下载了十几个字符串,下面是我需要解析的示例。

“澳大利亚 036 AUD 1 4,713831 4,728015 4,742199”

“Vel. Britanija 826 GBP 1 10,300331 10,331325 10,362319”

所以我的第一个想法是手动计算我需要的数字在哪里(第二个,4,728015 或 10,331325 在示例中)并获取子字符串。(52,8) 但后来我意识到我正在解析的字符串中很少有 >9 的数字,所以我需要一个 (51,9) 的子字符串来处理这种情况,所以我不能这样做

第二个想法是将所有的数字(如字符)保存在一个向量中,然后获取向量[4]并将其保存到一个单独的变量中。

第三个是循环字符串,直到我将自己定位在第 5 组空格之后,然后将其子串。

只是寻找一些关于什么是“最佳”的反馈。

【问题讨论】:

  • 使用 getline 创建以空格分隔的子字符串。合并早期的,直到你有 7 个。使用第 5 组
  • 数据格式使得优雅的解决方案变得困难,尤其是因为第一个字段中允许有空格。我建议阅读一行文本并搜索第一个非数字字符;它定义了第一个字段的内容。其余字段可以使用std::istringstreamoperator>> 提取。
  • 这里有点新手,我能麻烦你提供一个代码示例吗?
  • 你想让别人帮你做作业吗?
  • 这叫做“寻求帮助”。我相信你在新手时曾经使用过这种技术。

标签: c++ string algorithm loops


【解决方案1】:

问题

是我们可以在字符串的开头有多个单词。 IE。第一个元素可能包含空格。

解决方案

从我们稳定的字符串末尾开始。

在空格处拆分字符串。从末尾开始计数,然后选择上一个到最后一个元素。

解决方案 1:提升字符串算法

#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;

string extractstring(string & fullstring)
{
    vector<string> vs;
    split(vs, fullstring);
    return vs[vs.size() - 2];
}

解决方案 2:QString(来自 Qt 框架)

#include <QString>
QString extractstring(QString & fullstring)
{
    QStringlist sl = fullstring.split(" ");
    return sl[vs.size() - 2];
}

解决方案 3:仅 STL

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>

using namespace std;

string extractstring(string & fullstring) 
{
    istringstream iss(fullstring);
    vector<string> elements;
    copy(istream_iterator<string>(iss),
         istream_iterator<string>(),
         back_inserter(elements));
    return elements[elements.size() - 2];
}

其他解决方案:正则表达式、C 指针杂技。

更新:

我不会使用基于sscanf 的解决方案,因为可能难以识别字符串开头的多个单词。

【讨论】:

    【解决方案2】:

    我相信您可以使用sscanf 用一行代码完成它?

    http://www.cplusplus.com/reference/cstdio/sscanf/

    例如(http://ideone.com/e2cCT9):

    char *str = "Australija 4,713831 4,728015 4,742199";
    char tmp[255];
    int a,b,c,d;
    sscanf(str, "%*[^0-9] %d,%d %d,%d", &a, &b, &c, &d);
    
    printf("Parsed values: %d %d %d %d\n",a,b,c,d);
    

    【讨论】:

    • 好吧,我不确定我不能告诉函数专门从字符串中选择第二个十进制数。
    • @puernos 请更具体地说明您希望如何解析字符串并阅读文档
    • 不管怎样,我只需要在一个单独的变量中获取第二个数字,这样我就可以将它保存在地图中。
    • @sp2danny 更新了格式字符串。现在它将跳过所有字符并仅获取数字。
    【解决方案3】:

    障碍是第一个字段允许有空格,但其余字段用空格分隔。

    这可能不优雅,但这个概念应该有效:

    std::string text_line;
    getline(my_file, text_line);
    std::string::size_type field_1_start;
    const unsigned int text_length = text_line.length();
    for (field_1_start = 0; field_1_start < text_length; ++field_1_start)
    {
      if (is_digit(text_line[field_1_start])
      {
        break;
      }
    }
    if (field_1_start < text_length)
    {
      std::string remaining_text = text_line.substr(field_1_start, text_length - field_1_start);
      std::istringstream input_data(remaining_text);
      int field_1;
      std::string field2;
      input_data >> field_1;
      input_data >> field_2;
      //...
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-12
      • 1970-01-01
      • 2011-10-15
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      相关资源
      最近更新 更多