首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解析C++字符串

解析C++字符串
EN

Stack Overflow用户
提问于 2015-01-25 08:50:36
回答 3查看 154关注 0票数 0

这里有很多关于发布字符串的帖子,但实际上似乎不符合我的目的。

我使用的是std::string和所有的C++标准库,我有一个使用以下协议的文本文件:

代码语言:javascript
复制
TEXT1:TEXT2-TAB-TEXT3:TEXT4 TEXT5

-TAB-\t时。

我想把所有的文本都放到字符串中(也可以是数组)。文件中的所有行都是这样写的,我试着使用istringstream,但是它没有像:iss >> text1 >> ":" >> text2 >> "\t" >> text3 >> ":" >> text4 >> " " >> text5这样的功能。

我真的需要使用find的基本功能进行解析吗?这将是一堆工作(因为我有几个文件以不同的格式编写,我需要为所有这些编写一个通用函数),如果我别无选择的话,我会这样做的。

所以..。有任何方法可以使用字符串之间的已知字符来解析字符串吗?它不是一个特定的分隔符,因为每一行都包含一对分隔符(一次是空格,然后是冒号等等)。我想使用C++标准库,而不是像Boost这样的任何外部库。

编辑: C++11.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-25 09:06:38

由于您使用的是C++11,并且您的文本行遵守协议,那么用于模式匹配和信息提取的工具就是regex库中的特性。

与你的协议匹配的模式可能是这样的.

\W+:\W+-\t-\w+:W+\s+w+

..。使用默认的ECMAScript语法。还有其他几个。

接下来,使用原始字符串文字初始化regex对象..。

regex pat{R(“w+:\W+-t-\w+:\W+\s+”)};

所以现在你的代码可以这样..。

代码语言:javascript
复制
#include<regex>
...

regex pat{R("\w+:\w+-\t-\w+:\w+\s\w+")};
smatch m;

while (cin >> str) {  // where str is your line of formatted text
    bool match = regex_search(str, m, pat);
    for (int i = 0; i < m.size(); i++) {
        cout << m[i].str() << " "; // to make sure each component was matched
    }   
}

顺便说一句,smatch像一个容器一样工作,可以迭代,所以非常方便。

注意事项:上面的代码不能保证工作正常,它被用作指南。

票数 6
EN

Stack Overflow用户

发布于 2015-01-25 09:26:25

因为您有一个固定的字符来标记每个字段的结束,所以任何类似regexes的边界都是过头的。我只需要使用std::getline来读取每个字段。

首先,为一行中的字段定义一个struct,然后重载operator>>以读取其中一个结构:

代码语言:javascript
复制
struct line { 
    std::string text1, text2, text3, text4, text5;

    friend std::istream &operator>>(std::istream &is, line &l) {
        std::getline(is, l.text1, ':');
        std::getline(is, l.text2, '\t');
        std::getline(is, l.text3, ':');
        std::getline(is, l.text4, ' ');
        std::getline(is, l.text5);
        return is;
    }
};

这样,您就可以读到这样的一行:

代码语言:javascript
复制
line x;

std::cin >> x;

...or,如果整个文件中都有这样的行,则可以将它们全部读入向量中,如下所示:

代码语言:javascript
复制
std::ifstream infile("whatever.dat");

std::vector<line> lines {
    std::istream_iterator<line>(lines),
    std::istream_iterator<line>()
};
票数 3
EN

Stack Overflow用户

发布于 2015-01-25 08:54:11

您可能应该使用std::getline读取整行,然后解析该行,例如使用发现std:string方法查找'\t'字符。

如果可能的话,至少切换到C++11,因为C++11的许多特性将使您能够编写更少的代码。特别是,当与匿名std:找到一起使用时,来自<algorithm>兰卜达是有用的。

当然,您应该更正式地定义可接受的输入(可能有一些EBNF符号,至少在注释中)。特别是,在您的TEXT1TEXT2以及TEXT3TEXT4TEXT5中可以显示哪些确切的字符。在什么编码?(UTF-8有多字节字符!)。

如果输入规范很复杂,可以考虑使用一些解析器生成器,如等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28134746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档