さよなら煩わしい検索!C++のstd::basic_string_view::containsでスマートに文字列を見つけよう
メソッドの動作
このメソッドは、以下の引数を取ります。
pos
: 検索を開始する位置 (デフォルトは 0)sub
: 検索対象となる部分文字列ビュー
メソッドは、sub
が this
に 1 回以上出現するかどうか を調べ、true
または false
を返します。
例
#include <iostream>
#include <string_view>
int main() {
std::string_view haystack = "Hello, world!";
std::string_view needle = "world";
// "world" が "Hello, world!" に含まれているかどうかを確認
if (haystack.contains(needle)) {
std::cout << "needle が haystack に含まれています" << std::endl;
} else {
std::cout << "needle が haystack に含まれていません" << std::endl;
}
// 検索開始位置を指定
if (haystack.contains(needle, 7)) {
std::cout << "needle が haystack の 7 文字目以降に含まれています" << std::endl;
} else {
std::cout << "needle が haystack の 7 文字目以降に含まれていません" << std::endl;
}
return 0;
}
この例では、haystack
に needle
が含まれているかどうかを 2 回チェックしています。1 回目はデフォルトの開始位置 (0) で、2 回目は pos
を 7 に設定して検索を開始しています。
std::basic_string_view::contains
は、C++20 で導入された比較的新しい機能です。古いバージョンの C++ コンパイラを使用している場合は、この機能を使用できない可能性があります。std::basic_string_view::contains
は、効率的な検索アルゴリズム を使用しています。そのため、長い文字列を検索する場合でも、比較的短い時間で処理することができます。std::basic_string_view::contains
は、部分文字列マッチ のみを行います。つまり、needle
がhaystack
の先頭に一致するかどうかのみを調べます。完全一致を確認するには、std::basic_string_view::find
メソッドを使用する必要があります。
部分文字列の存在チェック
#include <iostream>
#include <string_view>
int main() {
std::string_view haystack = "Hello, world!";
std::string_view needles[] = {
"Hello",
"world",
"Good bye",
};
for (std::string_view needle : needles) {
if (haystack.contains(needle)) {
std::cout << needle << " は haystack に含まれています" << std::endl;
} else {
std::cout << needle << " は haystack に含まれていません" << std::endl;
}
}
return 0;
}
このコードは、haystack
という文字列ビューに、needles
配列に格納されている複数の部分文字列が含まれているかどうかを調べます。
大文字小文字を無視した検索
#include <iostream>
#include <string_view>
#include <algorithm>
int main() {
std::string_view haystack = "Hello, World!";
std::string_view needle = "world";
// 大文字小文字を無視して検索
if (std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), std::equal_insensitive)) {
std::cout << needle << " は haystack に含まれています (大文字小文字を無視した場合)" << std::endl;
} else {
std::cout << needle << " は haystack に含まれていません (大文字小文字を無視した場合)" << std::endl;
}
return 0;
}
このコードは、std::search
アルゴリズムと std::equal_insensitive
関数を使って、haystack
に needle
が 大文字小文字を無視して 含まれているかどうかを調べます。
#include <iostream>
#include <string_view>
#include <sstream>
int main() {
std::string_view haystack = "This is a string with multiple words.";
std::string_view delimiter = " ";
std::string_view needle = "words";
std::istringstream iss(haystack);
std::string_view token;
while (std::getline(iss, token, delimiter)) {
if (token.contains(needle)) {
std::cout << needle << " は " << token << " に含まれています" << std::endl;
}
}
return 0;
}
以下に、std::basic_string_view::contains
の代替となるいくつかの方法をご紹介します。
std::find を使用する
std::find
アルゴリズムは、ある範囲内に特定の値が含まれているかどうかを調べることができます。以下のコードは、std::basic_string_view::contains
と同等の機能を提供します。
bool contains(std::string_view haystack, std::string_view needle) {
return std::find(haystack.begin(), haystack.end(), needle.begin(), needle.end()) != haystack.end();
}
カスタム関数を使用する
独自の検索ロジックを実装したい場合は、カスタム関数を作成することができます。以下のコードは、std::basic_string_view::contains
と同等の機能を提供する単純な例です。
bool contains(std::string_view haystack, std::string_view needle) {
for (size_t i = 0; i < haystack.size() - needle.size() + 1; ++i) {
if (haystack.substr(i, needle.size()) == needle) {
return true;
}
}
return false;
}
正規表現を使用する
正規表現を使用すれば、より複雑な検索パターンを記述することができます。以下のコードは、std::basic_string_view::contains
と同等の機能を提供する std::regex
を使用した例です。
#include <regex>
bool contains(std::string_view haystack, std::string_view needle) {
std::regex re(needle);
return std::regex_search(haystack, re);
}
Boost.StringView ライブラリを使用する
Boost.StringView ライブラリは、C++ 標準ライブラリの std::string_view
クラスを拡張するものです。このライブラリには、contains
メソッドを含むいくつかの便利な機能が含まれています。
#include <boost/sview/string_view.hpp>
bool contains(boost::sview::string_view haystack, boost::sview::string_view needle) {
return haystack.contains(needle);
}
どの代替方法を使用すべきか
どの代替方法を使用するかは、状況によって異なります。
- Boost.StringView ライブラリを使用している場合は、このライブラリの
contains
メソッドを使用することができます。 - 複雑な検索パターンを記述する必要がある場合は、正規表現を使用するのが良いでしょう。
- カスタムの検索ロジックが必要な場合は、カスタム関数を作成する必要があります。
- シンプルで分かりやすい方法が必要な場合は、
std::find
を使用するのが良いでしょう。
- 保守性: 将来的に変更が必要になった場合に、コードを簡単に更新できるようにする必要があります。
- 可読性: コードは、他の開発者にとって読みやすく理解しやすいように記述する必要があります。
- パフォーマンス: それぞれの方法のパフォーマンスは異なります。ベンチマークを実施して、最適な方法を選択することが重要です。