优雅的字符串解析解决方案
Posted
技术标签:
【中文标题】优雅的字符串解析解决方案【英文标题】:Elegant solution for string parsing 【发布时间】:2015-09-13 17:37:43 【问题描述】:所以我下载了十几个字符串,下面是我需要解析的示例。
“澳大利亚 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::istringstream
和operator>>
提取。
这里有点新手,我能麻烦你提供一个代码示例吗?
你想让别人帮你做作业吗?
这叫做“寻求帮助”。我相信你在新手时曾经使用过这种技术。
【参考方案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;
//...
【讨论】:
以上是关于优雅的字符串解析解决方案的主要内容,如果未能解决你的问题,请参考以下文章