将\ r \ n分隔的字符串拆分为字符串数组[C / C ++]

时间:2014-11-30 02:45:48

标签: c++ arrays regex split line-breaks

我的字符串包含例如"FirstWord\r\nSecondWord\r\nThird Word\n\r"等等...... 我想使用vector <string>将其拆分为字符串数组,所以我会得到:

FileName[0] == "FirstWord";
FileName[1] == "SecondWord"; 
FileName[2] == "Third Word";

另外,请注意第三个字符串中的空格。

这是我到目前为止所得到的:

string text = Files; // Files var contains the huge string of lines separated by \r\n
vector<string> FileName; // (optionaly) Here I want to store the result without \r\n

regex rx("[^\\s]+\r\n");
sregex_iterator FormatedFileList(text.begin(), text.end(), rx), rxend;

while(FormatedFileList != rxend)
{
    FileName.push_back(FormatedFileList->str().c_str());
    ++FormatedFileList;
}

它有效,但当涉及第三个字符串"Third Word\r\n"时,它只给我"Word\r\n"

任何人都可以向我解释正则表达式如何工作?我有点困惑。

4 个答案:

答案 0 :(得分:4)

\s匹配所有空格,包括常规空格,制表符和其他一些空格。您只想排除\r\n,因此您的正则表达式应为

regex rx("[^\r\n]+\r\n");

编辑:这不适合评论,也不会详尽无遗 - 正则表达式是一个相当复杂的主题,但我会尽力给出一个粗略的解释。如果你学习正式语言,所有这些都会更有意义,所以我鼓励你阅读它,并且网上有无数的正则表达式教程,它们会更详细,你也应该阅读。好。

您的代码使用sregex_iterator遍历正则表达式text匹配的字符串rx中的所有位置,然后将它们转换为字符串并保存它们。那么,什么是正则表达式?

正则表达式是一种将模式匹配应用于字符串的方法。这可以从简单的子字符串搜索到......以及复杂的子字符串搜索。例如,您可以搜索"oba",然后搜索"foobar"后跟的任何字符,而不只是在字符串"oo"中查找"a"的实例,并在{ {1}}以及"foobar"

为了启用这种模式搜索,您必须有一种方法来指定您要查找的模式,其中一种方式是正则表达式。细节因实现而异,但一般来说,它的工作原理是定义与特殊事物匹配的特殊字符或修改模式其他部分的行为。这听起来令人困惑,所以让我们考虑一些例子:

  • 句点"foonarf"匹配任何单个字符
  • Kleene明星.后面的东西匹配零个以上的东西
  • *后跟的内容将匹配该内容的一个或多个实例
  • 方括号+[包含一组字符;整个事情然后匹配任何一个角色。
  • 插入符号]反转了括号表达式的选择

仍然令人困惑。所以让我们把它放在一起:

^

是使用oo.a 的正则表达式。这将匹配&#34; oo.a&#34;,&#34; ooba&#34;,&#34; oona&#34;,&#34; oo | a&#34;以及其他任何两个后跟一个字符后跟一个a的东西。它不会匹配&#34; ooa&#34;,&#34; oba&#34;或&#34;废话&#34;。

.

将匹配&#34;&#34;,&#34; a&#34;,&#34; aa&#34;,&#34; aaa&#34;,以及仅包含&#的任何其他序列39;但没有别的。

a*

将匹配任何&#34; foobar&#34;,&#34; goobar&#34;和&#34; hoobar&#34;,没有别的。

[fgh]oobar

将匹配&#34; aoobar&#34;,&#34; boobar&#34;,&#34; coobar&#34;等等但不是&#34; foobar&#34;,&#34; goobar&#34;和&#34; hoobar&#34;。

[^fgh]oobar

将匹配&#34; aoobar&#34;,&#34; aboobar&#34;,&#34; abcoobar&#34;,但不会&#34; oobar&#34;,&#34; foobar&#34 ;,&#34; agoobar&#34;,&#34; abhoobar&#34;。

在你的情况下,

[^fgh]+oobar

将匹配一个或多个字符的任何实例,这些字符既不是[^\r\n]+\r\n 也不是\r,后跟\n。然后,您遍历所有这些匹配并保存\r\n的匹配部分。

这就像我相信我可以合理地去这里一样深。这个兔子洞非常深,这意味着你可以用正则表达式制作怪异的东西,但你不应该期望在一两天内掌握它们。其中大部分内容与我刚才概述的内容相符,但是以真正的程序员方式,大多数正则表达式实现超出了常规语言和表达式的数学范围,并引入了有用但令人头脑的东西。龙是领先的,但旅程是值得的。

答案 1 :(得分:1)

一个简单的替代方案是使用Boost的split_regex。例如。 split_regex(out,input,boost :: regex(&#34;(\ r \ n)+&#34;))其中out是字符串向量,input是输入字符串。下面粘贴了一个完整的示例:

#include <vector>
#include <iostream>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>

using std::endl;
using std::cout;
using std::string;
using std::vector;
using boost::algorithm::split_regex;

int main()
{
    vector<string> out;
    string input = "aabcdabc\r\n\r\ndhhh\r\ndabcpqrshhsshabc";
    split_regex(out, input, boost::regex("(\r\n)+"));
    for (auto &x : out) {
        std::cout << "Split: " << x << std::endl;
    }
    return 0;
}

答案 2 :(得分:0)

regex rx("[^\\s]+\r\n");,似乎您正在尝试匹配字符串而不是拆分字符串。这个[^\\s]否定字符类意味着匹配任何字符但不匹配空格(水平空格或换行符)。在第三行中,有一个水平空格,因此您的正则表达式匹配水平空间旁边的文本。在多行模式下,.将匹配任何字符,但不匹配换行符。您可以使用regex rx(".+\r\n");代替regex rx("[^\\s]+\r\n");

答案 3 :(得分:0)

这也是一种方法:

char * pch = strtok((LPSTR)Files.c_str(), "\r\n");
while(pch != NULL)
{
    FileName.push_back(pch);
    pch = strtok(NULL, "\r\n");
}