得到一个不知道长度为c ++的子字符串

时间:2015-04-10 19:02:40

标签: c++ string

在阅读c ++电子书时,我想到了下一个问题:

假设我们有一个任意长度的字符串str。此字符串包含两个单词startend。我们的想法是在startend之间获取字符串的子字符串。有没有办法让结果与string::substr的结果相似但却不知道startend之间的距离?当然,我的意思是使用copy和迭代器或任何循环都很容易。但也许在string中实施了一种方法?我在c ++参考资料中找不到一个。

4 个答案:

答案 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