C#の文字列検索をマスターしよう!

C#の文字列検索をマスターしよう!のアイキャッチイメージ

C#の文字列の検索とは?

プログラム言語における「文字列の検索」とは、検索対象の文字列に指定した文字列があるかどうか、ある場合はどの位置にあるかを判定する処理のことです。もちろんC#においても同様で、C#は文字列が扱いやすく、C言語などよりも簡単に文字列の検索を行えます。

なおC#にはString.Compareのような文字列の検索ではなく、文字列の比較のための機能もありますが、今回は検索について説明するので省きます。

String.IndexOfが文字列検索の基本

C#の文字列検索でいちばん使いやすく機能が多いメソッドはString.IndexOfでしょう。このメソッドは検索対象の文字列に、指定した文字列が0から数えて何文字目にあるかを返します。指定した文字列が無い場合は-1を返します。以下はその簡単な使用例です。

string str = “これは文字列検索のテストです。”;

Console.WriteLine(str.IndexOf(“テスト”));
Console.WriteLine(str.IndexOf(“てすと”));
Console.WriteLine(str.IndexOf(“これ”));

手軽に使えるString.IndexOf

上の例を実行すると以下のような結果になります。

9
-1
0

“テスト”は0から数えて9文字目、”てすと”は平仮名なので一致せず-1、”これ”は先頭なので0になります。

なおString.IndexOfは検索開始位置を指定することができます。以下がその例です。

string str = “テストです、テストなのです。”;
Console.WriteLine(str.IndexOf(“テスト”, 1));

結果は6になります。0から数えて1文字目から検索するので、検索対象が”ストです、テストなのです。”となって6文字目になります。

末尾から逆方向に検索するString.LastIndexOf

String.LastIndexOfはIndexOfとは違い、文字列の先頭方向からではなく末尾方向から検索します。以下が使用例です。

string str = “テストです、テストなのです。”;

Console.WriteLine(str.LastIndexOf(“テスト”));
Console.WriteLine(str.LastIndexOf(“テスト”,8));
Console.WriteLine(str.LastIndexOf(“テスト”,7));

結果は以下になります。

6
6
0

1つ目のLastIndexOfは末尾から先頭方向に向かって検索して6文字目で”テスト”を検出しています。2つ目は8文字目から検索してすぐに”テスト”を検出したので1つ目と同じ結果です。しかし3つ目は7文字目からのため、”テストです、テス”の末尾から検索し始めるので、0文字目の結果を返すのです。

複数のchar文字を検索できるString.IndexOfAny

String.IndexOfAnyは文字列に指定したchar配列のどれかが含まれていた場合、その位置を返します。以下が使用例です。

string str = “これは文字列検索の\nテストです。”;
char[] c_ary = { ‘\n’, ‘\t’, ‘ ‘ };

Console.WriteLine(str.IndexOfAny(c_ary));

結果は\nの位置の9を返します。使い道が限られそうですが、このサンプルのように文字列に改行コードやタブ、半角スペース等が入っているかどうかを検出する時には便利でしょう。

大文字と小文字の区別をせずに検索する

文字列検索では大文字と小文字の区別をせずに検索したい時もあるでしょう。そのやり方は以下の通りです。

string str = “半角大文字のTEST、全角小文字のtest”;

Console.WriteLine(str.IndexOf(“test”, StringComparison.OrdinalIgnoreCase));
Console.WriteLine(str.IndexOf(“TEST”, StringComparison.OrdinalIgnoreCase));

これを実行すると以下のように表示されます。

6
17

IndexOfの第二引数にStringComparison.OrdinalIgnoreCaseを指定すれば、半角でも全角でも大文字小文字を無視した検索ができます。

かなとカナ、全角と半角の区別をせずに検索する

日本語の文字列の検索では、かなとカナの違いや全角・半角の違いを無視した検索をしたい時があるでしょう。C#ではCompareInfoを使えば可能です。以下が例になります。

string str = “平仮名のてすと、全角のテスト”;

System.Globalization.CompareInfo coinfo = System.Globalization.CultureInfo.CurrentCulture.CompareInfo;

Console.WriteLine(coinfo.IndexOf(str, “テスト”, System.Globalization.CompareOptions.IgnoreKanaType));
Console.WriteLine(coinfo.IndexOf(str, “テスト”, System.Globalization.CompareOptions.IgnoreWidth));

かなとカナの違いを無視したい場合はIgnoreKanaTypeを、全角と半角の違いを無視したい場合はIgnoreWidthを指定します。結果は、以下になります。

4
11

濁音無視、記号無視で検索する

CompareInfoを使うと、以下のような非常に変わった検索をすることもできます。

string str = “綺麗なガーベラ、かわいいチ?ュー!リ。ッ、プ”;

System.Globalization.CompareInfo coinfo = System.Globalization.CultureInfo.CurrentCulture.CompareInfo;

Console.WriteLine(coinfo.IndexOf(str, “カーヘラ”, System.Globalization.CompareOptions.IgnoreNonSpace));
Console.WriteLine(coinfo.IndexOf(str, “チューリップ”, System.Globalization.CompareOptions.IgnoreSymbols));

IgnoreNonSpaceを指定すると濁点を無視できます。IgnoreSymbolsを指定すると記号が無視されます。結果は以下になります。

3
12

この機能を使う機会はなかなか無いと思いますが、頭の片隅に置いておくといつか役に立つかもしれません。

文字列の先頭や末尾が一致するかどうか調べる

文字列の先頭や末尾が指定した文字列に完全一致するかどうかを知りたいことは多いでしょう。C#では以下のようにすれば出来ます。

string str = “この文字列の先頭と末尾を調べたい。”;

Console.WriteLine(str.StartsWith(“この文”));
Console.WriteLine(str.EndsWith(“たい”));
Console.WriteLine(str.EndsWith(“い。”));

結果は以下の通りです。一致するとTrue、一致しなければFalseを返します。

True
False
True

StartsWithを使わなくてもIndexOfで0が返れば先頭であることがわかりますし、EndsWithについてもLengthで文字列の長さを取得すればIndexOfで同じ事は出来ます。

ただ先頭や末尾を調べるならStartsWith、EndsWithを使う方がプログラムの意図が分かりやすくなるので、積極的に活用しましょう。

正規表現を使う

C#は正規表現を使った高度な文字列検索も可能です。例えば以下のようなことができます。なおこれを実行する場合はソースの先頭に”using System.Text.RegularExpressions;”を追加してください。

string str = “30歳の誕生日を迎えました!”;
Console.WriteLine(Regex.IsMatch(str, “^[0-9][0-9].+誕生日|節目.+!$”));

Regex.IsMatchの指定は「先頭が2桁の数字で、その後に1文字以上の文字列が続き、その後に”誕生日”か”節目”という言葉があって、その後に1文字以上の文字列が続き、最後が”!”で終わる」という意味です。

これを実行するとTrueが表示されます。正規表現はとても奥が深く、マスターすれば非常に高度な文字列の検索ができるようになります。文字列検索を極めたい人は是非チャレンジしてみてください。

おわりに

C#の文字列の検索について簡単に説明しましたがいかがでしたでしょうか。文字列の検索の機能はとても多岐に渡り、いくら学んでも終わりがない程の膨大な領域です。それでもこの記事の内容を押さえておけば困ることはまずないので、是非マスターしてくださいね。

インフラエンジニア専門の転職サイト「FEnetインフラ」

FEnetインフラはサービス開始から10年以上『エンジニアの生涯価値の向上』をミッションに掲げ、多くのエンジニアの就業を支援してきました。

転職をお考えの方は気軽にご登録・ご相談ください。