C++ 文字列型で後方一致の検索【std::string endsWith/hasSuffix 接尾辞判定】

C++の文字列クラスstd::stringには、接尾辞(サフィックス)を検索するためのメソッドとしてends_withendsWithhasSuffixが定義されていません。指定の文字列が特定の文字列で終わるかどうかを判定したい場合には、findメンバ関数、compareメンバ関数、std::equal関数による代用が必要となります。

目次

前方一致については、別記事の「前方一致の判定」が参考になります。

スポンサーリンク

後方一致(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と同じ値になってしまう)

ends_with関数

より処理効率の高いends_with関数の定義例は以下の通りです。指定の文字列がsuffixに指定された文字列で終わるかどうかを判定することができます。

// #include <algorithm> // std::equal
// #include <iterator>  // std::rbegin, std::rend
// ends_with("abc", "bc") == true
bool ends_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));
}

広告