ここではStringクラスに用意されている機能のうち、文字列が他の文字列と一致するかどうかの判定や、部分文字列の位置を取得するなどといった文字列の探索と比較を行うためのメソッド等について見ていきます。

ここで解説する文字列の探索・比較の操作と、対応するStringクラスのメソッドを表にまとめます。 個々のメソッドの詳細については順に解説していきます。

文字列操作と対応するStringクラスのメソッド
文字列操作 対応するStringクラスのメソッド 解説へのリンク
部分文字列の探索
(部分文字列の位置の取得)
IndexOf (前方からの探索)
LastIndexOf (後方からの探索)
解説へ
任意の一文字の探索
(文字の位置の取得)
IndexOfAny (前方からの探索)
LastIndexOfAny (後方からの探索)
解説へ
部分文字列を含むかどうかの判定
(部分一致の判定)
Contains 解説へ
部分文字列で始まるかどうかの判定
(前方一致の判定)
StartsWith 解説へ
部分文字列で終わるかどうかの判定
(後方一致の判定)
EndsWith 解説へ
nullまたは空の文字列かどうかの判定 IsNullOrEmpty 解説へ
null、空の文字列、または空白のみかどうかの判定 IsNullOrWhiteSpace 解説へ
文字列が等しいかどうかの判定 Equals 解説へ
等価演算子・不等価演算子 解説へ
文字列の大小関係の比較 Compare, CompareTo 解説へ
序数による文字列の大小関係の比較 CompareOrdinal 解説へ
文字列操作 対応するStringクラスのメソッド 解説へのリンク

上記以外のメソッドやここでは扱わない事項・関連する事項に関しては以下を参照してください。

文字列の探索

ここでは文字列の探索などを行うためのメソッドについて見ていきます。

部分文字列の探索 (IndexOf, LastIndexOf)

String.IndexOfメソッドは文字列内にある部分文字列の位置を探索するメソッドで、文字列内にある部分文字列の最初のインデックスを返します。 文字列内に部分文字列がない場合は-1が返されます。

String.IndexOfメソッドを使って部分文字列のある位置を探索する
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s.IndexOf("fox"));
    Console.WriteLine(s.IndexOf("lazy dog"));
    Console.WriteLine(s.IndexOf("cat")); // 文字列sに部分文字列"cat"が存在しないため、-1が返される
  }
}
String.IndexOfメソッドを使って部分文字列のある位置を探索する
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    Console.WriteLine(s.IndexOf("fox"))
    Console.WriteLine(s.IndexOf("lazy dog"))
    Console.WriteLine(s.IndexOf("cat")) ' 文字列sに部分文字列"cat"が存在しないため、-1が返される
  End Sub
End Class
実行結果
16
35
-1

String.LastIndexOfメソッドは、IndexOfメソッドとは逆に後ろから探索を行い、文字列内にある部分文字列の最後のインデックスを返します。 文字列内に部分文字列がない場合はIndexOfメソッドと同様に-1が返されます。

String.LastIndexOfメソッドを使って部分文字列のある位置を文字列の末尾側から探索する
using System;

class Sample {
  static void Main()
  {
    var s = "foo bar foo";

    Console.WriteLine(s.IndexOf("foo")); // 先頭側から見て最初にある"foo"の位置が返される
    Console.WriteLine(s.LastIndexOf("foo")); // 末尾側から見て最初にある"foo"の位置が返される

    // 部分文字列が見つからない場合は、どちらも-1を返す
    Console.WriteLine(s.IndexOf("baz"));
    Console.WriteLine(s.LastIndexOf("baz"));
  }
}
String.LastIndexOfメソッドを使って部分文字列のある位置を文字列の末尾側から探索する
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "foo bar foo"

    Console.WriteLine(s.IndexOf("foo")) ' 先頭側から見て最初にある"foo"の位置が返される
    Console.WriteLine(s.LastIndexOf("foo")) ' 末尾側から見て最初にある"foo"の位置が返される

    ' 部分文字列が見つからない場合は、どちらも-1を返す
    Console.WriteLine(s.IndexOf("baz"))
    Console.WriteLine(s.LastIndexOf("baz"))
  End Sub
End Class
実行結果
0
8
-1
-1

IndexOfメソッド、LastIndexOfメソッドでは文字列ではなく文字(char)の位置を探索することも出来ます。 文字列内に指定された文字がない場合は同様に-1が返されます。

String.IndexOf・LastIndexOfメソッドを使って特定の文字のある位置を探索する
using System;

class Sample {
  static void Main()
  {
    var s = "foo bar foo";

    Console.WriteLine(s.IndexOf('o'));
    Console.WriteLine(s.LastIndexOf('o'));
    Console.WriteLine(s.IndexOf('x'));
    Console.WriteLine(s.LastIndexOf('x'));
  }
}
String.IndexOf・LastIndexOfメソッドを使って特定の文字のある位置を探索する
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "foo bar foo"

    Console.WriteLine(s.IndexOf("o"c))
    Console.WriteLine(s.LastIndexOf("o"c))
    Console.WriteLine(s.IndexOf("x"c))
    Console.WriteLine(s.LastIndexOf("x"c))
  End Sub
End Class
実行結果
1
10
-1
-1

IndexOfメソッド、LastIndexOfメソッドでは、文字列比較時の動作をStringComparisonで指定することができます。 例えば、大文字小文字の違いを無視して部分文字列が一致するかどうかを調べることが出来ます。

String.IndexOf・LastIndexOfメソッドで大文字小文字の違いを無視する
using System;

class Sample {
  static void Main()
  {
    var s = "foo bar foo";

    Console.WriteLine(s.IndexOf("FOO", StringComparison.InvariantCulture)); // 大文字小文字の違いを無視しない
    Console.WriteLine(s.IndexOf("FOO", StringComparison.InvariantCultureIgnoreCase)); // 大文字小文字の違いを無視する
    Console.WriteLine(s.LastIndexOf("FOO", StringComparison.InvariantCulture));
    Console.WriteLine(s.LastIndexOf("FOO", StringComparison.InvariantCultureIgnoreCase));
  }
}
String.IndexOf・LastIndexOfメソッドで大文字小文字の違いを無視する
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "foo bar foo"

    Console.WriteLine(s.IndexOf("FOO", StringComparison.InvariantCulture)) ' 大文字小文字の違いを無視しない
    Console.WriteLine(s.IndexOf("FOO", StringComparison.InvariantCultureIgnoreCase)) ' 大文字小文字の違いを無視する
    Console.WriteLine(s.LastIndexOf("FOO", StringComparison.InvariantCulture))
    Console.WriteLine(s.LastIndexOf("FOO", StringComparison.InvariantCultureIgnoreCase))
  End Sub
End Class
実行結果
-1
0
-1
8

文字列比較時のオプションStringComparisonについては文字列と比較オプション・カルチャの並べ替え規則 §.StringComparison列挙型とStringComparerクラスで詳しく説明しています。

任意の文字の探索 (IndexOfAny, LastIndexOfAny)

String.IndexOfAnyメソッドは指定された複数の文字の中で、文字列内で見つかった最初の位置を探索するメソッドです。 IndexOfメソッドと同様に、いずれの文字も見つからなかった場合は-1が返されます。

String.IndexOfAnyメソッドで複数の文字のうちのいずれかがある位置を探索する
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    // q, w, eのいずれかの文字が最初に現れる位置を取得する
    Console.WriteLine(s.IndexOfAny(new char[] {'q', 'w', 'e'}));

    // R, T, Yのいずれかの文字が最初に現れる位置を取得する
    Console.WriteLine(s.IndexOfAny(new char[] {'R', 'T', 'Y'}));
  }
}
String.IndexOfAnyメソッドで複数の文字のうちのいずれかがある位置を探索する
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    ' q, w, eのいずれかの文字が最初に現れる位置を取得する
    Console.WriteLine(s.IndexOfAny(New Char() {"q"c, "w"c, "e"c}))

    ' R, T, Yのいずれかの文字が最初に現れる位置を取得する
    Console.WriteLine(s.IndexOfAny(New Char() {"R"c, "T"c, "Y"c}))
  End Sub
End Class
実行結果
2
0

String.LastIndexOfAnyメソッドは、IndexOfAnyメソッドとは逆に後ろから探索を行い、文字列内で見つかった最後の位置を返します。

String.LastIndexOfAnyメソッドで複数の文字のうちのいずれかがある一番後ろの位置を探索する
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    // a, e, oのいずれかの文字が最初に現れる位置を取得する
    Console.WriteLine(s.IndexOfAny(new char[] {'a', 'e', 'o'}));

    // a, e, oのいずれかの文字が最後に現れる位置を取得する
    Console.WriteLine(s.LastIndexOfAny(new char[] {'a', 'e', 'o'}));
  }
}
String.LastIndexOfAnyメソッドで複数の文字のうちのいずれかがある一番後ろの位置を探索する
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    ' a, e, oのいずれかの文字が最初に現れる位置を取得する
    Console.WriteLine(s.IndexOfAny(New Char() {"a"c, "e"c, "o"c}))

    ' a, e, oのいずれかの文字が最後に現れる位置を取得する
    Console.WriteLine(s.LastIndexOfAny(New Char() {"a"c, "e"c, "o"c}))
  End Sub
End Class
実行結果
2
41

部分文字列の一致 (Contains, StartsWith, EndsWith)

String.Containsメソッドは文字列中に部分文字列が含まれているかどうかを調べるメソッドです。 部分文字列が含まれている場合(=IndexOfメソッドの結果が-1以外となる場合)はtrueが返されます。

String.Containsメソッドで文字列が含まれているか調べる
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s.Contains("fox")); // 文字列sに"fox"が含まれているかどうか
    Console.WriteLine(s.Contains("lazy dog"));
    Console.WriteLine(s.Contains("cat"));
  }
}
String.Containsメソッドで文字列が含まれているか調べる
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    Console.WriteLine(s.Contains("fox")) ' 文字列sに"fox"が含まれているかどうか
    Console.WriteLine(s.Contains("lazy dog"))
    Console.WriteLine(s.Contains("cat"))
  End Sub
End Class
実行結果
True
True
False

String.StartsWithメソッドは文字列が指定された部分文字列で始まるかどうかを調べるメソッドです。 逆に、String.EndsWithメソッドは部分文字列で終わるかどうかを調べるメソッドです。

String.StartsWith・EndsWithメソッドで指定した文字列で始まるか・終わるかを調べる
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s.StartsWith("The"));  // 文字列が"The"で始まるか
    Console.WriteLine(s.StartsWith("lazy")); // 文字列が"lazy"で始まるか
    Console.WriteLine(s.EndsWith("dog"));    // 文字列が"dog"で終わるか
    Console.WriteLine(s.EndsWith("cat"));    // 文字列が"cat"で終わるか
  }
}
String.StartsWith・EndsWithメソッドで指定した文字列で始まるか・終わるかを調べる
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    Console.WriteLine(s.StartsWith("The"))  ' 文字列が"The"で始まるか
    Console.WriteLine(s.StartsWith("lazy")) ' 文字列が"lazy"で始まるか
    Console.WriteLine(s.EndsWith("dog"))    ' 文字列が"dog"で終わるか
    Console.WriteLine(s.EndsWith("cat"))    ' 文字列が"cat"で終わるか
  End Sub
End Class
実行結果
True
False
True
False

StartsWithメソッド・EndsWithメソッドでは、文字列比較時の動作をStringComparisonで指定することができます。 例えば、大文字小文字の違いを無視して部分文字列が一致するかどうかを調べることができます。

String.StartsWith・EndsWithメソッドで大文字小文字の違いを無視する
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    // 文字列が"the"で始まるかどうか調べる
    Console.WriteLine(s.StartsWith("the", StringComparison.Ordinal));           // 大文字小文字の違いを無視しない
    Console.WriteLine(s.StartsWith("the", StringComparison.OrdinalIgnoreCase)); // 大文字小文字の違いを無視する

    // 文字列が"DOG"で終わるかどうか調べる
    Console.WriteLine(s.EndsWith("DOG", StringComparison.Ordinal));
    Console.WriteLine(s.EndsWith("DOG", StringComparison.OrdinalIgnoreCase));
  }
}
String.StartsWith・EndsWithメソッドで大文字小文字の違いを無視する
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    ' 文字列が"the"で始まるかどうか調べる
    Console.WriteLine(s.StartsWith("the", StringComparison.Ordinal))           ' 大文字小文字の違いを無視しない
    Console.WriteLine(s.StartsWith("the", StringComparison.OrdinalIgnoreCase)) ' 大文字小文字の違いを無視する

    ' 文字列が"DOG"で終わるかどうか調べる
    Console.WriteLine(s.EndsWith("DOG", StringComparison.Ordinal))
    Console.WriteLine(s.EndsWith("DOG", StringComparison.OrdinalIgnoreCase))
  End Sub
End Class
実行結果
False
True
False
True

Containsメソッドも同様に、文字列比較時の動作をStringComparisonで指定することができます。 ただし、ContainsメソッドにStringComparisonを指定できるオーバーロードは、.NET Standard 2.1/.NET Core 2.1以降でのみ使用できます。

String.Containsメソッドで大文字小文字の違いを無視する .NET Standard 2.1/.NET Core 2.1
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    // 文字列中に"Brown Fox"が含まれるかどうか調べる
    Console.WriteLine(s.Contains("Brown Fox", StringComparison.Ordinal));           // 大文字小文字の違いを無視しない
    Console.WriteLine(s.Contains("Brown Fox", StringComparison.OrdinalIgnoreCase)); // 大文字小文字の違いを無視する
  }
}
String.Containsメソッドで大文字小文字の違いを無視する .NET Standard 2.1/.NET Core 2.1
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    ' 文字列中に"Brown Fox"が含まれるかどうか調べる
    Console.WriteLine(s.Contains("Brown Fox", StringComparison.Ordinal))           ' 大文字小文字の違いを無視しない
    Console.WriteLine(s.Contains("Brown Fox", StringComparison.OrdinalIgnoreCase)) ' 大文字小文字の違いを無視する
  End Sub
End Class
実行結果
False
True

文字列比較時のオプションStringComparisonについては文字列と比較オプション・カルチャの並べ替え規則 §.StringComparison列挙型とStringComparerクラスで詳しく説明しています。


.NET Standard 2.1/.NET Core 2.0以降において、StartsWithおよびEndsWithメソッドは、IndexOf・LastIndexOfメソッドと同様にcharを引数にとるバージョンが用意されているため、文字単位で一致を調べることができます。 Containsメソッドも同様に、.NET Standard 2.1/.NET Core 2.1以降でcharを引数にとるバージョンが用意されています。

String.StartsWith・EndsWithメソッドで指定した文字で始まるか・終わるかを調べる .NET Standard 2.1/.NET Core 2.0
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    // .NET Standard 2.1/.NET Core 2.0以降では、StartsWith/EndsWithメソッドにcharも指定できる
    Console.WriteLine(s.StartsWith('T'));  // 文字列が'T'で始まるか
    Console.WriteLine(s.StartsWith('l'));  // 文字列が'l'で始まるか
    Console.WriteLine(s.EndsWith('g'));    // 文字列が'g'で終わるか
    Console.WriteLine(s.EndsWith('t'));    // 文字列が't'で終わるか
  }
}
String.StartsWith・EndsWithメソッドで指定した文字で始まるか・終わるかを調べる .NET Standard 2.1/.NET Core 2.0
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    ' .NET Standard 2.1/.NET Core 2.0以降では、StartsWith/EndsWithメソッドにcharも指定できる
    Console.WriteLine(s.StartsWith("T"c))  ' 文字列が'T'で始まるか
    Console.WriteLine(s.StartsWith("l"c))  ' 文字列が'l'で始まるか
    Console.WriteLine(s.EndsWith("g"c))    ' 文字列が'g'で終わるか
    Console.WriteLine(s.EndsWith("t"c))    ' 文字列が't'で終わるか
  End Sub
End Class
実行結果
True
False
True
False
String.Containsメソッドで指定した文字が含まれているかを調べる .NET Standard 2.1/.NET Core 2.1
using System;

class Sample {
  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    // .NET Standard 2.1/.NET Core 2.1以降では、Containsメソッドにcharも指定できる
    Console.WriteLine(s.Contains('q')); // 文字'q'を含むかどうか
    Console.WriteLine(s.Contains('Q')); // 文字'Q'を含むかどうか
  }
}
String.Containsメソッドで指定した文字が含まれているかを調べる .NET Standard 2.1/.NET Core 2.1
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    ' .NET Standard 2.1/.NET Core 2.1以降では、Containsメソッドにcharも指定できる
    Console.WriteLine(s.Contains("q"c)) ' 文字'q'を含むかどうか
    Console.WriteLine(s.Contains("Q"c)) ' 文字'Q'を含むかどうか
  End Sub
End Class
実行結果
True
False

Contains・StartsWith・EndsWithの各メソッドでは、charを引数にとるオーバーロードでも文字列比較時の動作をStringComparisonで指定することができます。 文字列比較時のオプションStringComparisonについては文字列と比較オプション・カルチャの並べ替え規則 §.StringComparison列挙型とStringComparerクラスで詳しく説明しています。

それ以外のバージョンでは、Contains・StartsWith・EndsWithの各メソッドにcharを引数にとるバージョンが用意されていないので、文字単位での一致を調べることはできません。 文字列が指定された文字で始まる/終わる/含むかどうかを調べるには、IndexOf・LastIndexOfメソッドを使う必要があります。

次の例は、IndexOf・LastIndexOfメソッドを使って、charを引数にとるContains・StartsWith・EndsWithメソッドを実装したものです。

charを引数にとるContains・StartsWith・EndsWithメソッド
using System;

class Sample {
  // 文字列sが指定された文字cを含むかどうか調べるメソッド
  static bool Contains(string s, char c)
  {
    return s.IndexOf(c) != -1;
  }

  // 文字列sが指定された文字cで始まるかどうか調べるメソッド
  static bool StartsWith(string s, char c)
  {
    return s.IndexOf(c) == 0;
    // もしくは単純に
    // return s[0] == c;
  }

  // 文字列sが指定された文字cで終わるかどうか調べるメソッド
  static bool EndsWith(string s, char c)
  {
    return s.LastIndexOf(c) == s.Length - 1;
    // もしくは単純に
    // return s[s.Length - 1] == c;
  }

  static void Main()
  {
    var s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(Contains(s, 'f'));    // 文字列が'f'を含むか
    Console.WriteLine(Contains(s, 'A'));    // 文字列が'A'を含むか
    Console.WriteLine(StartsWith(s, 'T'));  // 文字列が'T'で始まるか
    Console.WriteLine(StartsWith(s, 'l'));  // 文字列が'l'で始まるか
    Console.WriteLine(EndsWith(s, 'g'));    // 文字列が'g'で終わるか
    Console.WriteLine(EndsWith(s, 't'));    // 文字列が't'で終わるか
  }
}
charを引数にとるContains・StartsWith・EndsWithメソッド
Imports System

Class Sample
  ' 文字列sが指定された文字cを含むかどうか調べるメソッド
  Shared Function Contains(ByVal s As String, ByVal c As Char) As Boolean
    Return s.IndexOf(c) <> -1
  End Function

  ' 文字列sが指定された文字cで始まるかどうか調べるメソッド
  Shared Function StartsWith(ByVal s As String, ByVal c As Char) As Boolean
    Return s.IndexOf(c) = 0
    ' もしくは単純に
    ' Return s(0) = c
  End Function

  ' 文字列sが指定された文字cで終わるかどうか調べるメソッド
  Shared Function EndsWith(ByVal s As String, ByVal c As Char) As Boolean
    Return s.LastIndexOf(c) = s.Length - 1
    ' もしくは単純に
    ' Return s(s.Length - 1) = c
  End Function

  Shared Sub Main()
    Dim s As String = "The quick brown fox jumps over the lazy dog"

    Console.WriteLine(Contains(s, "f"c))    ' 文字列が'f'を含むか
    Console.WriteLine(Contains(s, "A"c))    ' 文字列が'A'を含むか
    Console.WriteLine(StartsWith(s, "T"c))  ' 文字列が'T'で始まるか
    Console.WriteLine(StartsWith(s, "l"c))  ' 文字列が'l'で始まるか
    Console.WriteLine(EndsWith(s, "g"c))    ' 文字列が'g'で終わるか
    Console.WriteLine(EndsWith(s, "t"c))    ' 文字列が't'で終わるか
  End Sub
End Class
実行結果
True
False
True
False
True
False

文字列の比較・等価性の検証

ここでは文字列の比較・等価性の検証などを行うためのメソッドについて見ていきます。

null、空文字、空白のチェック (IsNullOrEmpty, IsNullOrWhiteSpace)

String.IsNullOrEmptyメソッドは文字列がnull/Nothingもしくは空文字かどうかをチェックする静的メソッドです。

String.IsNullOrWhiteSpaceメソッドは.NET Framework 4から追加されたメソッドで、文字列がnull/Nothingもしくは空文字か、空白文字のみで構成されているかどうかをチェックする静的メソッドです。

String.IsNullOrEmpty・IsNullOrWhiteSpaceメソッドで、文字列がnullもしくは空文字か、空白文字のみで構成されているかを調べる
using System;

class Sample {
  static void Main()
  {
    var s = "foo";

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s));
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s));

    s = "   "; // 空白のみの文字列

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s)); // 空白のみの文字列の場合はfalseとなる
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s)); // 空白のみの文字列の場合はtrueとなる

    s = ""; // 空(長さ0)の文字列

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s));
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s));

    s = null; // nullが代入されている文字列変数

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s));
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s));
  }
}
String.IsNullOrEmpty・IsNullOrWhiteSpaceメソッドで、文字列がnullもしくは空文字か、空白文字のみで構成されているかを調べる
Imports System

Class Sample
  Shared Sub Main()
    Dim s As String = "foo"

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s))
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s))

    s = "   " ' 空白のみの文字列

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s)) ' 空白のみの文字列の場合はFalseとなる
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s)) ' 空白のみの文字列の場合はTrueとなる

    s = "" ' 空(長さ0)の文字列

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s))
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s))

    s = Nothing ' Nothingが代入されている文字列変数

    Console.WriteLine("<{0}> : IsNullOrEmpty = {1}", s, String.IsNullOrEmpty(s))
    Console.WriteLine("<{0}> : IsNullOrWhiteSpace = {1}", s, String.IsNullOrWhiteSpace(s))
  End Sub
End Class
実行結果
<foo> : IsNullOrEmpty = False
<foo> : IsNullOrWhiteSpace = False
<   > : IsNullOrEmpty = False
<   > : IsNullOrWhiteSpace = True
<> : IsNullOrEmpty = True
<> : IsNullOrWhiteSpace = True
<> : IsNullOrEmpty = True
<> : IsNullOrWhiteSpace = True

このメソッドでは、半角および全角のスペースやタブだけでなく、改行文字なども空白文字として扱われます。 具体的には、Unicodeで空白文字と定義されている文字(Char.IsWhiteSpacetrueとなる文字)が空白文字として扱われます。


なお、IsNullOrEmptyメソッド、IsNullOrWhiteSpaceメソッドの動作は、次のコードと等価です。

IsNullOrEmptyメソッド・IsNullOrWhiteSpaceメソッドと同じ動作を行うメソッドの実装
static bool IsNullOrEmpty(string s)
{
  if (s == null)
    return true;
  else if (s.Length == 0)
    return true;
  else
    return false;
}

static bool IsNullOrWhiteSpace(string s)
{
  if (IsNullOrEmpty(s))
    return true;
  else if (s.Trim().Length == 0)
    return true;
  else
    return false;
}
IsNullOrEmptyメソッド・IsNullOrWhiteSpaceメソッドと同じ動作を行うメソッドの実装
Shared Function IsNullOrEmpty(ByVal s As String) As Boolean
  If s Is Nothing Then
    Return True
  Else If s.Length = 0 Then
    Return True
  Else
    Return False
  End If
End Function

Shared Function IsNullOrWhiteSpace(ByVal s As String) As Boolean
  If IsNullOrEmpty(s) Then
    Return True
  Else If s.Trim().Length = 0 Then
    Return True
  Else
    Return False
  End If
End Function

比較 (CompareTo, Equals, Compare)

String.CompareToメソッドString.Equalsメソッドは文字列の比較を行うメソッドで、指定された文字列と比較した結果を返します。

CompareToメソッドの戻り値は、二つの文字列を並べ替えた時の順番に従い、次のようになります。 比較の際、null/Nothingは空文字を含むどのような文字列よりも小さいと判断され、null/Nothing同士は等価として扱われます。

String.CompareToの戻り値
文字列aとbの関係 a.CompareTo(b)の戻り値
並べ替えたときにaの方がbよりも前
(aはbよりも小さい)
0より小さい値 "ABC" < "ABD"
null < "ABC"
並べ替えたときにaとbは同じ位置
(aとbは等しい)
0 "ABC" = "ABC"
null = null
並べ替えたときにaの方がbよりも後
(aはbよりも大きい)
0より大きい値 "ABC" > "ABB"
"ABC" > null

Equalsメソッドは、二つの文字列が等しい場合(CompareToメソッドが0を返す場合)にTrueを返します。

String.CompareTo・Equalsメソッドで別の文字列との大小関係・等価関係の比較を行う
using System;

class Sample {
  static void Main()
  {
    var s1 = "foo";
    var s2 = "bar";
    var s3 = "baz";

    Console.WriteLine("{0} CompareTo {1} : {2}", s1, s2, s1.CompareTo(s2));
    Console.WriteLine("{0} CompareTo {1} : {2}", s1, s3, s1.CompareTo(s3));
    Console.WriteLine("{0} CompareTo {1} : {2}", s2, s3, s2.CompareTo(s3));
    Console.WriteLine("{0} CompareTo {1} : {2}", s2, s2, s2.CompareTo(s2));

    Console.WriteLine("{0} Equals {1} : {2}", s1, s2, s1.Equals(s2));
    Console.WriteLine("{0} Equals {1} : {2}", s1, s3, s1.Equals(s3));
    Console.WriteLine("{0} Equals {1} : {2}", s2, s3, s2.Equals(s3));
    Console.WriteLine("{0} Equals {1} : {2}", s2, s2, s2.Equals(s2));
  }
}
String.CompareTo・Equalsメソッドで別の文字列との大小関係・等価関係の比較を行う
Imports System

Class Sample
  Shared Sub Main()
    Dim s1 As String = "foo"
    Dim s2 As String = "bar"
    Dim s3 As String = "baz"

    Console.WriteLine("{0} CompareTo {1} : {2}", s1, s2, s1.CompareTo(s2))
    Console.WriteLine("{0} CompareTo {1} : {2}", s1, s3, s1.CompareTo(s3))
    Console.WriteLine("{0} CompareTo {1} : {2}", s2, s3, s2.CompareTo(s3))
    Console.WriteLine("{0} CompareTo {1} : {2}", s2, s2, s2.CompareTo(s2))

    Console.WriteLine("{0} Equals {1} : {2}", s1, s2, s1.Equals(s2))
    Console.WriteLine("{0} Equals {1} : {2}", s1, s3, s1.Equals(s3))
    Console.WriteLine("{0} Equals {1} : {2}", s2, s3, s2.Equals(s3))
    Console.WriteLine("{0} Equals {1} : {2}", s2, s2, s2.Equals(s2))
  End Sub
End Class
実行結果
foo CompareTo bar : 1
foo CompareTo baz : 1
bar CompareTo baz : -1
bar CompareTo bar : 0
foo Equals bar : False
foo Equals baz : False
bar Equals baz : False
bar Equals bar : True

String.Compareメソッドは、CompareToメソッドと同じ動作をする静的メソッドです。 Equalsメソッドは、静的メソッドとしても用意されています。 戻り値はインスタンスメソッドの場合と同じです。

String.Compareの戻り値
文字列aとbの関係 String.Compare(a, b)の戻り値
並べ替えたときにaの方がbよりも前
(aはbよりも小さい)
0より小さい値 "ABC" < "ABD"
null < "ABC"
並べ替えたときにaとbは同じ位置
(aとbは等しい)
0 "ABC" = "ABC"
null = null
並べ替えたときにaの方がbよりも後
(aはbよりも大きい)
0より大きい値 "ABC" > "ABB"
"ABC" > null
String.Compare・Equalsメソッドで2つの文字列の大小関係・等価関係の比較を行う
using System;

class Sample {
  static void Main()
  {
    var s1 = "foo";
    var s2 = "bar";
    var s3 = "baz";

    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s2, String.Compare(s1, s2));
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s3, String.Compare(s1, s3));
    Console.WriteLine("Compare({0}, {1}) : {2}", s2, s3, String.Compare(s2, s3));
    Console.WriteLine("Compare({0}, {1}) : {2}", s2, s2, String.Compare(s2, s2));

    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s2, String.Equals(s1, s2));
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s3, String.Equals(s1, s3));
    Console.WriteLine("Equals({0}, {1}) : {2}", s2, s3, String.Equals(s2, s3));
    Console.WriteLine("Equals({0}, {1}) : {2}", s2, s2, String.Equals(s2, s2));
  }
}
String.Compare・Equalsメソッドで2つの文字列の大小関係・等価関係の比較を行う
Imports System

Class Sample
  Shared Sub Main()
    Dim s1 As String = "foo"
    Dim s2 As String = "bar"
    Dim s3 As String = "baz"

    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s2, String.Compare(s1, s2))
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s3, String.Compare(s1, s3))
    Console.WriteLine("Compare({0}, {1}) : {2}", s2, s3, String.Compare(s2, s3))
    Console.WriteLine("Compare({0}, {1}) : {2}", s2, s2, String.Compare(s2, s2))

    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s2, String.Equals(s1, s2))
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s3, String.Equals(s1, s3))
    Console.WriteLine("Equals({0}, {1}) : {2}", s2, s3, String.Equals(s2, s3))
    Console.WriteLine("Equals({0}, {1}) : {2}", s2, s2, String.Equals(s2, s2))
  End Sub
End Class
実行結果
Compare(foo, bar) : 1
Compare(foo, baz) : 1
Compare(bar, baz) : -1
Compare(bar, bar) : 0
Equals(foo, bar) : False
Equals(foo, baz) : False
Equals(bar, baz) : False
Equals(bar, bar) : True

インスタンスメソッドでも静的メソッドでも結果は同じですが、想定される状況により使い分けることが出来ます。 例えば、静的メソッドのCompareとEqualsを使うと、仮に文字列変数にnull/Nothingが代入されていてもヌル参照を引き起こさずに済みます。 (nullとの比較や、null同士の比較を行っても例外エラーにはなりません)

Stringクラスのインスタンスメソッド・静的メソッドの比較
using System;

class Sample {
  static void Main()
  {
    string s1 = null;
    var s2 = "foo";

    Console.WriteLine(String.Compare(s1, s2)); // s1がnullでもエラーにはならない
    Console.WriteLine(s1.CompareTo(s2)); // s1がnullであるためNullReferenceExceptionがスローされる
  }
}
Stringクラスのインスタンスメソッド・静的メソッドの比較
Imports System

Class Sample
  Shared Sub Main()
    Dim s1 As String = Nothing
    Dim s2 As String = "foo"

    Console.WriteLine(String.Compare(s1, s2)) ' s1がNothingでもエラーにはならない
    Console.WriteLine(s1.CompareTo(s2)) ' s1がNothingであるためNullReferenceExceptionがスローされる
  End Sub
End Class

CompareToメソッド、Compareメソッド、Equalsメソッドでは、文字列比較時の動作をStringComparisonで指定することができます。 例えば、大文字小文字の違いを無視して文字列の比較を行うことができます。

String.Compare・Equalsメソッドで大文字小文字の違いを無視する
using System;

class Sample {
  static void Main()
  {
    var s1 = "Bar";
    var s2 = "bar";
    var s3 = "BAR";

    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s2, String.Compare(s1, s2, StringComparison.InvariantCulture)); // 大文字小文字の違いを無視しない
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s2, String.Compare(s1, s2, StringComparison.InvariantCultureIgnoreCase)); // 大文字小文字の違いを無視する
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s3, String.Compare(s1, s3, StringComparison.InvariantCulture));
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s3, String.Compare(s1, s3, StringComparison.InvariantCultureIgnoreCase));

    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s2, String.Equals(s1, s2, StringComparison.InvariantCulture));
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s2, String.Equals(s1, s2, StringComparison.InvariantCultureIgnoreCase));
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s3, String.Equals(s1, s3, StringComparison.InvariantCulture));
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s3, String.Equals(s1, s3, StringComparison.InvariantCultureIgnoreCase));

  }
}
String.Compare・Equalsメソッドで大文字小文字の違いを無視する
Imports System

Class Sample
  Shared Sub Main()
    Dim s1 As String = "Bar"
    Dim s2 As String = "bar"
    Dim s3 As String = "BAR"

    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s2, String.Compare(s1, s2, StringComparison.InvariantCulture)) ' 大文字小文字の違いを無視しない
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s2, String.Compare(s1, s2, StringComparison.InvariantCultureIgnoreCase)) ' 大文字小文字の違いを無視する
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s3, String.Compare(s1, s3, StringComparison.InvariantCulture))
    Console.WriteLine("Compare({0}, {1}) : {2}", s1, s3, String.Compare(s1, s3, StringComparison.InvariantCultureIgnoreCase))

    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s2, String.Equals(s1, s2, StringComparison.InvariantCulture))
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s2, String.Equals(s1, s2, StringComparison.InvariantCultureIgnoreCase))
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s3, String.Equals(s1, s3, StringComparison.InvariantCulture))
    Console.WriteLine("Equals({0}, {1}) : {2}", s1, s3, String.Equals(s1, s3, StringComparison.InvariantCultureIgnoreCase))
  End Sub
End Class
実行結果
Compare(Bar, bar) : 1
Compare(Bar, bar) : 0
Compare(Bar, BAR) : -1
Compare(Bar, BAR) : 0
Equals(Bar, bar) : False
Equals(Bar, bar) : True
Equals(Bar, BAR) : False
Equals(Bar, BAR) : True

文字列比較時のオプションStringComparisonについては文字列と比較オプション・カルチャの並べ替え規則 §.StringComparison列挙型とStringComparerクラスで詳しく説明しています。

序数による比較 (CompareOrdinal)

String.CompareOrdinalメソッドは、Compareメソッド同様に文字列の比較を行う静的メソッドですが、比較の際に文字列の各文字を数値(Unicode序数Unicode ordinal)、つまり各文字のコードポイントでの比較を行う点で動作が異なります。

Compareメソッドでオプションを特に指定しない場合、現在のスレッドの(もしくは引数で指定された)カルチャの規則にしたがった比較を行うのに対し、CompareOrdinalメソッドでは常にカルチャに依存しない比較が行われます。

String.CompareOrdinalメソッドでコードポイントによって文字列を比較する
using System;

class Sample {
  static void Main()
  {
    var p1 = new string[] {"abc", "abd"};
    var p2 = new string[] {"coop", "co-op"};
    var p3 = new string[] {"cant", "can't"};

    Console.WriteLine("Compare       ({0}, {1}) : {2}", p1[0], p1[1], String.Compare(p1[0], p1[1]));
    Console.WriteLine("CompareOrdinal({0}, {1}) : {2}", p1[0], p1[1], String.CompareOrdinal(p1[0], p1[1]));

    Console.WriteLine("Compare       ({0}, {1}) : {2}", p2[0], p2[1], String.Compare(p2[0], p2[1]));
    Console.WriteLine("CompareOrdinal({0}, {1}) : {2}", p2[0], p2[1], String.CompareOrdinal(p2[0], p2[1]));

    Console.WriteLine("Compare       ({0}, {1}) : {2}", p3[0], p3[1], String.Compare(p3[0], p3[1]));
    Console.WriteLine("CompareOrdinal({0}, {1}) : {2}", p3[0], p3[1], String.CompareOrdinal(p3[0], p3[1]));
  }
}
String.CompareOrdinalメソッドでコードポイントによって文字列を比較する
Imports System

Class Sample
  Shared Sub Main()
    Dim p1 As String() = New String() {"abc", "abd"}
    Dim p2 As String() = New String() {"coop", "co-op"}
    Dim p3 As String() = New String() {"cant", "can't"}

    Console.WriteLine("Compare       ({0}, {1}) : {2}", p1(0), p1(1), String.Compare(p1(0), p1(1)))
    Console.WriteLine("CompareOrdinal({0}, {1}) : {2}", p1(0), p1(1), String.CompareOrdinal(p1(0), p1(1)))

    Console.WriteLine("Compare       ({0}, {1}) : {2}", p2(0), p2(1), String.Compare(p2(0), p2(1)))
    Console.WriteLine("CompareOrdinal({0}, {1}) : {2}", p2(0), p2(1), String.CompareOrdinal(p2(0), p2(1)))

    Console.WriteLine("Compare       ({0}, {1}) : {2}", p3(0), p3(1), String.Compare(p3(0), p3(1)))
    Console.WriteLine("CompareOrdinal({0}, {1}) : {2}", p3(0), p3(1), String.CompareOrdinal(p3(0), p3(1)))
  End Sub
End Class
実行結果
Compare       (abc, abd) : -1
CompareOrdinal(abc, abd) : -1
Compare       (coop, co-op) : -1
CompareOrdinal(coop, co-op) : 66
Compare       (cant, can't) : -1
CompareOrdinal(cant, can't) : 77

CompareメソッドとCompareOrdinalメソッドで大小関係が反転している箇所に注目してください。

CompareTo・Compare・Equalsの各メソッドでも、StringComparisonを指定することによってCompareOrdinalメソッドと同様の比較方法を使用するように指定できます。 これについては文字列と比較オプション・カルチャの並べ替え規則 §.StringComparison列挙型とStringComparerクラスで詳しく説明しています。

等価演算子(==, !=, <>)

C#、VB.NETでは等価演算子・不等価演算子を用いることで文字列同士の比較が行えます。 等価演算子の動作はEqualsメソッドと同等です。 つまりC#、VB.NETでのstring同士の等価演算子の結果は、String.Equals(a, b)と同じ動作となります。 不等価演算子は、その結果を否定(反転)したものとなります。

等価演算子・不等価演算子を使って文字列同士を比較する
using System;

class Sample {
  static void Main()
  {
    var s1 = "foo";
    var s2 = "bar";
    var s3 = "foo";

    Console.WriteLine("{0} == {1}: {2}", s1, s2, s1 == s2);
    Console.WriteLine("{0} != {1}: {2}", s1, s2, s1 != s2);
    Console.WriteLine("{0} == {1}: {2}", s1, s3, s1 == s3);
    Console.WriteLine("{0} != {1}: {2}", s1, s3, s1 != s3);
  }
}
等価演算子・不等価演算子を使って文字列同士を比較する
Imports System

Class Sample
  Shared Sub Main()
    Dim s1 As String = "foo"
    Dim s2 As String = "bar"
    Dim s3 As String = "foo"

    Console.WriteLine("{0} = {1}:  {2}", s1, s2, s1 = s2)
    Console.WriteLine("{0} <> {1}: {2}", s1, s2, s1 <> s2)
    Console.WriteLine("{0} = {1}:  {2}", s1, s3, s1 = s3)
    Console.WriteLine("{0} <> {1}: {2}", s1, s3, s1 <> s3)
  End Sub
End Class
実行結果
foo == bar: False
foo != bar: True
foo == foo: True
foo != foo: False

当然ながら、等価演算子・不等価演算子による比較の場合は、カルチャを無視したり大文字小文字を無視したりといった文字列比較時のオプション(StringComparison)を指定することはできません。 文字列比較時のオプションを指定する必要がある場合はEqualsメソッドを用います。

文字列の比較ではなく、文字列変数の参照の比較を行いたい場合、つまり2つの文字列変数が同一の文字列インスタンスを参照しているかどうかを調べるには、Object.ReferenceEqualsメソッドを使うことができます。 これについて詳しくは文字列とStringクラス §.参照と等価演算子で解説しています。


C#においては、等価演算子・不等価演算子がオーバーロードされていない限り、両辺がstringでないとコンパイルエラーとなります(タイプセーフ)。 一方、Equalsメソッドは引数にObject型をとるオーバーロードも用意されているため、stringと異なる型の比較を行おうとしてもコンパイルエラーにはなりません。

等価演算子・不等価演算子・Equalsメソッドでの文字列と他の型との比較
using System;

class Sample {
  static void Main()
  {
    var s = "16";
    var i = 16;

    // 等価演算子では、stringとintの比較はコンパイルエラーとなる
    Console.WriteLine(s == i); // error CS0019: 演算子 '==' を 'string' と 'int' 型のオペランドに適用することはできません。

    // Equalsメソッドでは、stringとintの比較はコンパイルエラーにはならない
    // また実行時にも例外はスローされない
    // 異なる型同士の比較となるので、結果はFalseとなる
    Console.WriteLine(String.Equals(s, i)); // False
  }
}

等価演算子とEqualsメソッドではパフォーマンスに若干の違いはありますが、どちらを使うのが妥当かは状況により異なるので、両者の違いを十分に考慮して選択する必要があります。

比較演算子 (<, <=, >, >=, Like)

(このドキュメントは未整理です)

VB.NETでは、不等号演算子、Like演算子を用いることでCompareメソッドと同等の比較が行えます。 比較時の動作は、Option Compareステートメントの設定により変わります。

C#では、不等号演算子による文字列の比較は行えないので、Compareメソッドを使用する必要があります。