[英]C++ Find last ocurrence of a string inside a substring
我需要一個方法來幫助我在另一個子字符串中找到一個字符串,換句話說,在其他字符串的子范圍內找到一個字符串。 此外,我需要以相反的順序找到它,因為我知道我正在尋找的字符串是關閉到用作“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。
您可以通過組合API來限制原始字符串中的搜索長度,並進行額外檢查以查看最終結果是否位於substr_beg
之前,從而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
如果它出現在substring的初始字符之前,則拒絕一個答案。 來自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
其他成員函數一起使用,則需要執行額外的步驟將結果范圍轉換為索引,就像此答案一樣 ,但如果不是,則只需使用范圍界面並避免使用std::string
的“有用”方法。
另一個選擇是使用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";
}
使用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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.