我需要一个方法来帮助我在另一个子字符串中找到一个字符串,换句话说,在其他字符串的子范围内找到一个字符串。此外,我需要以相反的顺序找到它,因为我知道我正在寻找的字符串关闭到用作" haystack"的子字符串的末尾。
让我们假设以下代码,其中rfind_in_substr
是我要求的方法:
std::string sample("An example with the example word example trice");
// substring "ample with the example wo"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
// (1)
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
// pos == 20, because its the index of the start of the second
// "example" word inside the main string.
当然,第(1)行可以替换为:
std::size_t pos = substr_beg + sample.substr
(substr_beg, substr_size).rfind("example");
但这意味着子串的不必要副本。是否有任何方法或C ++ / boost方法可以帮助我做到这一点?
我在看boost::algorithm::string
图书馆,但我一无所获(我已经理解了)。我知道C ++ 17有std::string_view
类,这是完美的,但我使用的是C ++ 14。
答案 0 :(得分:3)
您可以通过组合API来限制原始字符串中的搜索长度,并进行额外检查以查看最终结果是否在substr_beg
之前找到答案:
std::size_t rfind_in_substr(
const std::string& str
, const std::size_t from
, const std::size_t len
, const std::string& sub
) {
std::size_t res = str.rfind(sub, from+len-sub.size());
return res != string::npos && res >= from ? res : string::npos;
}
from+len-sub.size()
计算子字符串可以开始的最后位置。res >= from
拒绝答案,如果它出现在子字符串的初始字符之前。答案 1 :(得分:3)
来自Boost.StringAlgo:
#include <boost/algorithm/string/find.hpp>
auto haystack = boost::make_iterator_range(str.begin() + from, str.begin() + from + len);
auto found = boost::algorithm::find_last(haystack, needle);
现在,如果您需要将其与std::string
中的其他成员函数一起使用,则需要执行额外的步骤,将结果范围转换为this answer does之类的索引,但如果您不是t,然后只需使用范围界面,避免std::string
&#34;有用&#34;方法
另一种选择是使用boost::string_ref
,std::string_view
基本上是基于:
#include <iostream>
#include <boost/utility/string_ref.hpp>
std::size_t rfind_in_substr(std::string const& str, std::size_t from,
std::size_t len, std::string const& s)
{
return from + boost::string_ref(str).substr(from, len).rfind(s);
}
int main()
{
std::string sample("An example with the example word example trice");
// substring "ample with the example wo"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
// (1)
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
// pos == 20, because its the index of the start of the second
// "example" word inside the main string.
std::cout << pos << "\n";
}
答案 2 :(得分:2)
使用std::find_end
可以有效地解决问题而不需要使用超过需要的问题,但我希望有任何方法已经解决了这个问题:
#include <iostream>
#include <string>
#include <algorithm>
std::size_t rfind_in_substr(std::string const& str, std::size_t from,
std::size_t len, std::string const& s)
{
auto sub_beg = str.begin() + from;
auto sub_end = sub_beg + len;
auto found_it = std::find_end(sub_beg, sub_end, s.begin(), s.end());
if (found_it == sub_end)
return str.npos;
else
return found_it - str.begin();
}
int main()
{
std::string sample("An example with the example word example trice");
// substring "ample with the example w"
std::size_t substr_beg = 5;
std::size_t substr_size = 24;
std::size_t pos = rfind_in_substr(sample, substr_beg,
substr_size, "example");
std::cout << pos << std::endl; // Prints 20
}