我正在寻找一种方法将以下文本行拆分为数组。
这是一些文字\ r \ n“这里是另一行”\ r \ n和另一行
这样得到的数组是:
以下是一些文字
\ r \ n
“
这是另一行
“
\ r \ n
另一行
请注意,此处基本上有两个分隔符,“和 \ r \ n 。
我需要在C ++中这样做,将来可能会有额外的分隔符
有什么想法吗?
提前致谢。
编辑:不,这不是作业。
这是我到目前为止所拥有的:
const RWCString crLF = "\r\n";
const RWCString doubleQuote = "\"";
RWTValOrderedVector<RWCString> Split(const RWCString &value, const RWCString &specialContent)
{
RWTValOrderedVector<RWCString> result;
unsigned index = 0;
RWCString str = value;
while ( ( index = str.index( specialContent, 0, RWCString::ignoreCase ) ) != RW_NPOS )
{
RWCString line = str(0, index);
result.append(line);
result.append(specialContent);
str = str(index, str.length() - index);
str = str(specialContent.length(), str.length() - specialContent.length());
}
if (str.length() > 0)
{
result.append(str);
}
return result;
}
void replaceSpecialContents(const RWCString &value)
{
RWTValOrderedVector<RWCString> allStrings;
RWTValOrderedVector<RWCString> crLFStrings = Split(value, crLF);
for (unsigned i=0; i<crLFStrings.entries(); i++)
{
RWTValOrderedVector<RWCString> dqStrings = Split(crLFStrings[i], doubleQuote);
if (dqStrings.entries() == 1)
{
allStrings.append(crLFStrings[i]);
}
else
{
for (unsigned j=0; j<dqStrings.entries(); j++)
{
allStrings.append(dqStrings[j]);
}
}
}
}
答案 0 :(得分:2)
这是一种可以在C和C ++中使用的方法:
//String to tokenize:
char str[] = "let's get some tokens!";
//A set of delimiters:
char delims[] = " ";
//List of tokens:
char *tok1 = NULL,
*tok2 = NULL,
*tok3 = NULL;
//Tokenize the string:
tok1 = strtok(str, delims);
tok2 = strtok(NULL, delims); //after you get the first token
tok3 = strtok(NULL, delims); //supply "NULL" as first strtok parameter
你可以通过各种方式修改。您可以将所有“strtok(NULL,delims)”调用放在循环中以使其更灵活,您可以使用.c_str()等与C ++字符串接口。
答案 1 :(得分:1)
getline
有一个可选的分隔符,因此您只需花费很少的精力即可使用stringstream
来执行此分隔符。缺点是(我相信)它一次只能使用一个分隔符。
答案 2 :(得分:1)
将问题视为如下:
现在,解决1和2.如果有任何问题,请再次询问。
答案 3 :(得分:1)
您可以使用string::find_first_of
和string::substr
。小心检查“空”字符串; find_first_of
会找到char
s,因此\r
和\n
都会被生成的算法拆分。
或者,迭代整个字符串,并在遇到另一个分隔符时复制上一部分。
答案 4 :(得分:1)
一种非常简单的方法就是使用flex:
你可以在一些非常易读的行中为C ++应用程序构建一个非常简单的词法分析器。
我会注意到你应该小心'\ r \ n'。如果以文本模式(默认)打开文件,则标准流读取将标准行终止序列转换为'\ n'。在某些平台上,行终止序列的结尾为'\ r \ n',因此如果您从文件中读取流,则只能看到'\ n'字符。
%option c++
%option noyywrap
%%
\" return 1;
\r\n return 2;
[^"\r\n]* return 3;
%%
#include "FlexLexer.h"
int main()
{
yyFlexLexer lexer(&std::cin, &std::cout);
int token;
while((token = lexer.yylex()) != 0)
{
std::string tok(lexer.YYText(), lexer.YYText() + lexer.YYLeng());
std::cout << "Token: " << token << "(" << tok << ")\n";
}
}
% flex split.lex
% g++ main.cpp lex.yy.cc
% cat testfile | ./a.exe
Token: 3(Here is some text)
Token: 2(
)
Token: 1(")
Token: 3(here is another line)
Token: 1(")
Token: 2(
)
Token: 3(And another line)
答案 5 :(得分:1)
在您正在使用的Rogue Wave SourcePro API的基础上,您可以使用RWTRegex将字符串拆分为标记:
RWTValOrderedVector<RWCString> tokenize(const RWCString& str)
{
RWTRegex<char> re("\\r\\n|\"|([^\"\\r]|\\r[^\\n])*|\\r$");
RWTRegex<char>::iterator it(re, str);
RWTValOrderedVector<RWCString> result;
for (; it != RWTRegex<char>::iterator(); ++it) {
result.append(it->subString(str));
}
return result;
}
有关RWTRegex的详细信息,请参阅http://www.roguewave.com/Portals/0/products/sourcepro/docs/12.0/html/sourceproref/classRWTRegex.html。
答案 6 :(得分:0)
这是一种使用TR1正则表达式功能的方法。
std::string text("Here is some text\r\n\"here is another line\"\r\nAnd another line");
std::vector<std::string> vec;
std::regex rx("[\\w ]+|\\r\\n|\"");
std::sregex_iterator rxi(text.begin(), text.end(), rx), rxend;
for (; rxi != rxend; ++rxi)
{
vec.push_back(rxi->str());
}
在我的测试中,这会在您的示例中使用7个子字符串填充向量。我不是专家,所以可能有一个比我正在使用的更正确的正则表达式。
答案 7 :(得分:0)
strtok会用NULL替换你的令牌。这就是为什么它不包括令牌。
man strtok获取更多信息。我也在使用strtok和strtok_r,因为我有以下
的传入char数组你好~Milktea~这是我的留言\ r \ n消息〜我看了很好〜卡地亚\ r \ n
我将首先剥离〜(波浪线),然后是\ r \ n,反之亦然。