文字列の前方一致の判定にはstarts_with
メンバ関数を利用することができます(C++20以降)。
std::string{"abc"}.starts_with("ab") // true
ただしC++20より前の古いコンパイラの場合、C++の文字列クラスstd::string
には接頭辞(プレフィックス)を検索するためのメソッドとしてstarts_with
やstartsWith
、hasPrefix
等の関数が定義されていません。
そのため、指定の文字列が特定の文字列で始まるかどうかを判定したい場合には、std::equal
関数やfind
メンバ関数、compare
メンバ関数による代用が必要となります。
目次
- 前方一致(prefix search, starts with)
- starts_withメンバ関数による判定(C++20以降)
- std::equal関数による判定(高速で汎用的な方法)
- findメンバ関数による判定(単純明快な方法)
- compareメンバ関数による判定(比較的有名な方法)
- 文字/文字集合による判定(先頭一文字の判定を行う場合)
- start_with関数
後方一致については、別記事の「後方一致の判定」が参考になります。
前方一致(prefix search, starts with)
starts_withメンバ関数による判定
C++20以降のコンパイラであれば、starts_with
メンバ関数による前方一致の判定が可能となっています。
std::string s = "abc"; // 検索先の文字列
std::string t = "ab"; // 検索文字列
if (s.starts_with(t)) {
puts("文字列`ab`で始まる文字列です");
}
starts_withはstd::string_view
型の引数を受け取るメンバ関数として定義されています。そのためstd::string
型の値を渡すことも可能となっています。また引数には多重定義により、C言語スタイルの文字列(const char *
)や文字型(char
)を利用することもできます。
std::string{abc}.starts_with("ab"); // true
std::string{abc}.starts_with('a'); // true
std::equal関数による判定
std::string型文字列に対して、先頭文字列の一致を判定するためには、std::equal
関数による比較がもっとも効率的です。
// #include <algorithm> // std::equal
std::string s = "abc"; // 検索先の文字列
std::string t = "ab"; // 検索文字列
if (s.size() >= t.size() &&
std::equal(std::begin(t), std::end(t), std::begin(s))) {
puts("文字列`ab`で始まる文字列です");
}
C言語スタイルの文字列による検索を行う場合には、若干の改変が必要となります。
std::string s = "abc";
const char* t = "ab"; // 検索文字列(文字列ポインタ)
size_t n = std::char_traits<char>::length(t); // 検索文字列の長さ
if (s.size() >= n && std::equal(t, t + n, std::begin(s))) {
puts("文字列`ab`で始まる文字列です");
}
参考: std::equal関数
findメンバ関数による判定
先頭文字列の一致を判定するためには、findメンバ関数の利用がもっとも手っ取り早い方法ですが、長文検索時の処理効率はあまり良くありません。
std::string s = "abc";
if (s.find("ab") == 0) {
puts("文字列`ab`で始まる文字列です");
}
// char型の文字を検索することも可能
if (s.find('a') == 0) puts("文字`a`で始まる文字列です");
findメンバ関数は一致する文字列が見つかるまで全文を検索するため、先頭文字列が一致しなかった場合でも、文字列の末尾まで余計な検索が行われてしまうことになります。
参考: findメンバ関数
compareメンバ関数による判定
findメンバ関数は全文検索が発生する場合があるため、より効率的な処理を求める場合には、検索開始位置と終了位置の指定が可能なcompareメンバ関数への置き換えが有効です。
std::string s = "abc";
std::string t = "ab";
if (s.size() >= t.size() &&
s.compare(0, t.size(), t) == 0) {
puts("文字列`ab`で始まる文字列です");
}
ただし、compareメンバ関数は検索文字列の大小比較を伴うため、より処理効率の高いプログラムを求める場合には、冒頭で説明した「# std::equal関数による判定」による比較テクニックの利用が必要となります。
参考: compare メンバ関数
文字/文字集合による判定
char型の文字を検索する場合は添字アクセスの利用がより効率的な処理となります。
std::string s = "abc";
if (s[0] == 'a') puts("文字`a`で始まる文字列です");
find_first_ofメンバ関数を用いることで、複数の文字のいずれかの文字で始まるかどうかを判定することもできます。
std::string s = "abc";
if (s.find_first_of("Aa") == 0) {
puts("文字`A`または`a`で始まる文字列です");
}
start_with関数
以下はequal関数を用いたstart_with関数の実装例です。指定の文字列s
がprefix
に指定された文字列で始まるかどうかを判定することができます。
bool start_with(const std::string& s, const std::string& prefix) {
if (s.size() < prefix.size()) return false;
return std::equal(std::begin(prefix), std::end(prefix), std::begin(s));
}
assert( start_with("abc", "") );
assert( start_with("abc", "a") );
assert( start_with("abc", "ab") );
assert( start_with("abc", "abc") );
assert( !start_with("abc", "abcd") );