【C#】文字列のいろんな扱い方

2021年4月9日

こんにちは、ノムノムです。

今回は文字列を使ったあれこれを説明しようと思います。

実際に業務でも使っている内容なので参考になればうれしいです。

文字列から特定の文字の検索する方法

文字列から特定の文字を検索する方法を紹介します。

文字列を検索するときは、IndexOf関数を利用します。
IndexOf関数を利用すると指定した文字列の場所を返してくれます。見つからない場合は-1を返します。

エラーチェックなどで使います。それでサンプルコードを見てみましょう。

//文字列の取得
string str = this.textBox1.Text;

//文字列「orange」の検索
int index = str.IndexOf("orange", StringComparison.CurrentCultureIgnoreCase);

//検索失敗した場合は終了
if (index < 0)
{
    //検索値を表示
    this.textBox2.Text = "文字列「orange」はありません。";
    return;
}

//検索値を表示
this.textBox2.Text = (index + 1).ToString() + "文字目にあります。"; 

IndexOf関数の引数にStringComparison.CurrentCultureIgnoreCaseを加えることで大文字、小文字を区別せずに検索できます。
ただし、全角と半角は区別されますので注意してください。

取得したIndexは0から始まります。なので表示は+1しています。

先頭の文字列が指定した文字列かどうか調べる

先頭の文字列が指定した文字列と一致しているか確認するときはStartsWith関数を使うとよいです。

StartsWith関数は文字列の先頭が指定した文字列と一致すれば真(True)、一致しなければ偽(False)が返ります。

例えば文字列がURLであることを確認するには先頭がhttpから始まっているか確認すればいいです。

//文字列の取得
string str = this.textBox1.Text;

//文字列がURLか
bool isUrl = str.StartsWith("http", StringComparison.CurrentCultureIgnoreCase);

//結果を表示
this.textBox3.Text = isUrl.ToString();

5行目ですね。httpが先頭に来ているかチェックしています。結果は上記の画像の通りです。

もっと厳密にURLかどうか調べる方法は正規表現などを使った方法もあります。
以下の記事で紹介しています。

正規表現で検索がめっちゃ楽になる
正規表現で検索がめっちゃ楽になる
こんにちは、ノムノムです。 今回は、正規表現について説明しようと思います。その理由はですね。 私が開発したファ…
http://nomux2.net/regex/#toc_id_4_2

末尾の文字列が指定した文字列かどうか調べる

文字列の末尾が指定した文字列かどうかをチェックするにはEndsWith関数を利用します。

EndsWith関数は文字列の末尾が指定した文字列と一致すれば真(True)、一致しなければ偽(False)が返ります。

こちらは特定の拡張子の判別などに便利です。

//文字列の取得
string str = this.textBox1.Text;

//文字列がURLか
bool isJpg = str.EndsWith(".jpg", StringComparison.CurrentCultureIgnoreCase);

//結果を表示
this.textBox4.Text = isJpg.ToString();

この場合チェックするのが一つの拡張子の場合は便利ですが複数の拡張子をチェックしたい場合には使いにくいですので拡張子だけを取得して比較するのがいいかと思います。

拡張子の取得方法は以下の記事に記載しています。

【C#】ファイルのフルパスから情報を取得する
【C#】ファイルのフルパスから情報を取得する
こんにちは、ノムノムです。 今回はファイルのパスについていろいろやっていこうと思います。 パスっていうのはフォ…
http://nomux2.net/fileoperation/#toc_id_5

長文の文字列の結合をする方法

長文の文字列を扱うときは要注意、文字が長すぎると文字の結合に支障をきたしてしまいます。

よくあるのがCSVなんかのデータを読込みした結果を文字列に一度しまっておく場合です。

業務でもたまに見かけます。
CSVが10000行を超えるファイルは処理がとても時間がかかる

そこでStringBuilderを使います。

//文字列の取得
string str = "";
StringBuilder sb = new StringBuilder();

//ストップウォッチ
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

sw.Reset();
sw.Start();

//足す
for (int i = 0;i < this.numericUpDown1.Value; i++)
{
    str += this.textBox1.Text;
}

this.textBox5.Text = str;

sw.Stop();

//終了時間を表示
this.textBox6.Text = sw.Elapsed.ToString();

sw.Reset();
sw.Start();

//足す
for (int i = 0; i < this.numericUpDown1.Value; i++)
{
    sb.Append(this.textBox1.Text);
}

this.textBox8.Text = sb.ToString();

sw.Stop();

//終了時間を表示
this.textBox7.Text = sw.Elapsed.ToString();

StringBuilderは文字を追加する時Appendメソッドで追加していきます。(30行目)

どうでしょう。上記の画像を見てください。
こんな短い文の文字列を10000回足しただけでも1.2秒の差が出てきます。

ユーザにとって1.2秒の差というのは意外と長く感じるものです。

文字列が数値に変換できるかチェック

文字列変数を数値に変換したいと思います。

しかし必ずしもその文字列変数に数値が入っているとは限りません。
もし数値以外の文字が入っている場合エラーになってしまいます。

そこでTryParse関数を使います。以下の例を表示します。

//文字列の取得
string str = this.textBox1.Text;

//数値の変換
int num = 0;
bool sucess = int.TryParse(str, out num);

this.textBox9.Text = sucess ? "整数である" : "整数ではない";
if (sucess)
{
    //数値の場合は画面に変換された値を表示
    this.textBox10.Text = num.ToString();
} else
{
    this.textBox10.Text = "";
}

int.TryParse関数を使うと数値への変換を行ってくれます。成功するとtrueと変換後の数値、失敗するとfalseが返ってきます。

8行目はこれは三項演算子といって条件文となります。

= (条件式) ? (Trueの場合の値):(Falseの場合の値)

という結果を返すことができます。

結果は上記の画像のようになります。

文字列が日付に変換できるかチェック

文字列を数値に変換するのと同様に日付型(DateTime)のもTryParseがあります。

//文字列の取得
string str = this.textBox1.Text;

//数値の変換
DateTime date = System.DateTime.Now;
bool sucess = DateTime.TryParse(str, out date);

this.textBox11.Text = sucess ? "日付である" : "日付ではない";
if (sucess)
{
    this.textBox12.Text = date.ToString("yyyy/MM/dd HH:mm:ss");
}
else
{
    this.textBox12.Text = "";
}

6行目にDateTime.TryParse関数変換しています。
結果は上記の画像の通りです。

文字列を区切り文字で区切って配列にする

文字列を特定の文字列で区切って配列にするときはSplit関数が便利です。

例えばCSVファイルは文字がカンマ(,)区切りになっています。
こういった文字列を区切るのにSplit関数が便利です。

以下サンプルです。

//文字列の取得
string str = this.textBox1.Text;

//文字列をカンマで区切る
string[] str_array = str.Split(',');

this.listBox1.Items.Clear();
//配列をリストに表示
foreach (string item in str_array)
{
    this.listBox1.Items.Add(item);
}

これを実行すると上記の画像のようになります。

配列になった文字列をつなげる

Split関数は区切り文字で配列化するための関数でした。逆に配列の文字列をくっつけるJoin関数があります。

//文字列の取得
string str = this.textBox1.Text;

//文字列をカンマで区切る
string[] str_array = str.Split(',');

//配列を&でつなげて文字にする
this.textBox13.Text = string.Join("&", str_array);

str_arrayの文字配列を&でつなげると上記の画像のようになります。

文字列から特定の文字がいくつ入っているか確認する方法

ここは、ちょっとしたテクニックのようなものです。

例えばCSVファイルの項目数がいくつあるのか確認したい時に以下のように、カンマの数を数えて項目数を取得したりするときに使ったりします。

//文字列の取得
string str = this.textBox1.Text;

//Splitで数を数える方法
this.textBox14.Text = str.Split(',').Length.ToString();

//Replaceで数を数える方法
this.textBox15.Text = (str.Length - str.Replace(",", "").Length + 1).ToString();

Replaceを使った方法だとカンマの数を取得します。なので項目数を取得する場合は+1してあげます。

まとめ

文字列は、何かと使うことが多いため、こういった加工する方法を知っていると知らないとでは効率に差が出てきます。

これは文字列に限ったことではなく数値でもクラスでもありえることですので、身に付けておいた方がいいです。

ここまで読んで頂いてありがとうございます。