std::string文字列の後方一致の判定にはends_with
メンバ関数を利用することができます(C++20以降)。
std::string{"abc"}.ends_with("bc") // true
C++17以前の文字列クラスstd::string
には、接尾辞(サフィックス)を検索するためのメソッドとしてends_with
やendsWith
、hasSuffix
が定義されていません。指定の文字列が特定の文字列で終わるかどうかを判定したい場合には、find
メンバ関数、compare
メンバ関数、std::equal
関数による代用が必要となります。
目次
- ends_withメンバ関数による後方一致の判定(
C++20
以降) - 後方一致(suffix search, ends with match)(
find
,rfind
,compare
メンバ関数による検索) - ends_with関数(
std::equal
関数によるイテレータ比較)
前方一致については、別記事の「前方一致の判定」が参考になります。
ends_withメンバ関数による後方一致の判定
C++20以降のコンパイラであれば、ends_with
メンバ関数による前方一致の判定が可能となっています。
std::string s = "abc"; // 検索先の文字列
std::string t = "bc"; // 検索文字列
if (s.ends_with(t)) {
puts("文字列`bc`で終わる文字列です");
}
引数にはstd::string
(厳密にはstd::string_view
)型の文字列の他に、C言語スタイルの文字列(const char *
)や文字型(char
)を利用することができます。
std::string{abc}.ends_with("bc"); // true
std::string{abc}.ends_with('c'); // true
後方一致(suffix search, ends with match)
末尾文字列の一致を判定する方法については、find関数とその検索開始位置の指定を用いてこれを実現します。
std::string s = "abc"; // 検索先の文字列
std::string t = "bc"; // 検索したい文字列
if (s.size() >= t.size() &&
s.find(t, s.size() - t.size()) != std::string::npos) {
puts("文字列`bc`で終わる文字列です");
}
他にも、compareメンバ関数を用いる方法があります。
std::string s = "abc";
std::string t = "bc";
if (s.size() >= t.size() &&
s.compare(s.size() - t.size(), t.size(), t) == 0) {
puts("文字列`bc`で終わる文字列です");
}
rfind関数の利用法も知られていますが、全文に対する検索が行われるため処理効率はよくありません。仮に利用する場合にはnpos
による事前の比較が必須となります。rfindの結果をそのまま判定に利用してしまうと、オフセットによる誤差が発生し、正常な判定が行えなくなります。
/* 非推奨 */
std::string s = "abc";
std::string t = "bc";
std::string::size_type pos = s.rfind(t); // 不一致時に全文検索が発生
if (pos != std::string::npos &&
s.rfind(t) + t.size() == s.size()) {
puts("文字列`bc`で終わる文字列です");
}
/* 危険 */
std::string s = "abc";
std::string t = "abcd";
bool found = s.rfind(t) == s.size() - t.size();
found; // true (`s.size() - t.size()`はnposと同じ値になってしまう)
end_with関数
より処理効率の高いend_with関数の定義例は以下の通りです。指定の文字列がsuffixに指定された文字列で終わるかどうかを判定することができます。
// #include <algorithm> // std::equal
// #include <iterator> // std::rbegin, std::rend
// end_with("abc", "bc") == true
bool end_with(const std::string& s, const std::string& suffix) {
if (s.size() < suffix.size()) return false;
return std::equal(std::rbegin(suffix), std::rend(suffix), std::rbegin(s));
}