在阅读c ++电子书时,我想到了下一个问题:
假设我们有一个任意长度的字符串str
。此字符串包含两个单词start
和end
。我们的想法是在start
和end
之间获取字符串的子字符串。有没有办法让结果与string::substr
的结果相似但却不知道start
和end
之间的距离?当然,我的意思是使用copy
和迭代器或任何循环都很容易。但也许在string
中实施了一种方法?我在c ++参考资料中找不到一个。
答案 0 :(得分:1)
如果您有一个包含数据的字符串,并且您希望获得文本的起始位和结尾位之间的所有字符串,则可以使用以下内容。
std::string test = "this is a string we are searching through to get a substring";
std::string startText = "string";
std::string endText = "to";
size_t startPos, endPos;
startPos = test.find(startText, 0);
if (startPos == std::string::npos)
std::cout << "No Starting Text";
endPos = test.find(endText, startPos + 1);
if (endPos == std::string::npos)
std::cout << "No Ending Text";
std::string subString = test.substr(startPos + startText.size() + 1, endPos - startPos + startText.size());
std::cout << subString;
答案 1 :(得分:1)
最佳解决方案是找到第一次出现的os“start”和最后一次出现的“end”:
string get_substr_between_start_and_end(const string& s)
{
size_t start_pos = s.find("start");
size_t end_pos = s.rfind("end");
if((end_pos != string::npos) && (start_pos < end_pos)) //both are present
{
start_pos += 5; //skip "start"
return s.substr(start_pos, end_pos - start_pos);
}
return "";
}
如果“start”或“end”不存在,则返回空字符串。此功能适用于任何数量的“开始”和“结束”。例如:
int main()
{
string str_1 = "start and something between end";
string str_2 = "start and something between end and another end";
string str_3 = "start and second start and something between end and another end";
cout<<get_substr_between_start_and_end(str_1)<<endl;
cout<<get_substr_between_start_and_end(str_2)<<endl;
cout<<get_substr_between_start_and_end(str_3)<<endl;
return 0;
}
输出:
and something between
and something between end and another
and second start and something between end and another
实时样本:LINK。
答案 2 :(得分:1)
您可以使用类std :: string或标准算法的成员函数以不同方式执行任务。
以下是两种方法
第一个使用类std::string
#include <iostream>
#include <string>
#include <cstring>
int main()
{
std::string s( "startmiddleend" );
const char *start = "start";
const char *end = "end";
std::string t;
std::cout << s << std::endl;
auto pos = s.find( start );
if ( pos != std::string::npos )
{
pos += std::strlen( start );
auto n = s.find( end, pos );
if ( n == std::string::npos ) n = s.size();
t = s.substr( pos, n - pos );
}
std::cout << t << std::endl;
}
第二个使用标准算法std::search
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <iterator>
int main()
{
std::string s( "startmiddleend" );
const char *start = "start";
const char *end = "end";
std::string t;
std::cout << s << std::endl;
size_t n = std::strlen( start );
auto first = std::search( s.begin(), s.end(), start, start + n );
if ( first != s.end() )
{
std::advance( first, n );
t.assign( first, std::search( first, s.end(), end, end + std::strlen( end ) ) );
}
std::cout << t << std::endl;
}
两个程序都有相同的输出
程序输出
startmiddleend
middle
答案 3 :(得分:1)
问题的答案是否没有简单的方法来提取此类文字。
我碰巧有一个我之前准备的功能,它实现了这个功能。如果证明对某人有用,我会提供它:
#include <string>
#include <iostream>
using size_type = std::string::size_type;
size_type extract_delimited_text(const std::string& in
, const std::string& d1, const std::string& d2
, std::string& out, size_type pos = 0)
{
auto end = pos;
if((pos = in.find(d1, pos)) != std::string::npos)
{
if((end = in.find(d2, (pos = pos + d1.size()))) != std::string::npos)
{
out = in.substr(pos, end - pos);
return end + d2.size();
}
}
return std::string::npos;
}
int main()
{
std::string d1 = "${";
std::string d2 = "}";
std::string s = "find stuff ${to extract} and stuff and ${some more} stuff";
std::string sub;
std::string::size_type pos = 0;
// keep extracting all matches
while((pos = extract_delimited_text(s, d1, d2, sub, pos)) != std::string::npos)
std::cout << "sub: " << sub << '\n';
}
<强>输出:强>
sub: to extract
sub: some more