ここではStringクラスに用意されている機能のうち、文字列が他の文字列と一致するかどうかの判定や、部分文字列の位置を取得するなどといった文字列の探索と比較を行うためのメソッド等について見ていきます。
ここで解説する文字列の探索・比較の操作と、対応するStringクラスのメソッドを表にまとめます。 個々のメソッドの詳細については順に解説していきます。
文字列操作 | 対応するStringクラスのメソッド | 解説へのリンク |
---|---|---|
部分文字列の探索 (部分文字列の位置の取得) |
IndexOf (前方からの探索) LastIndexOf (後方からの探索) |
解説へ |
任意の一文字の探索 (文字の位置の取得) |
IndexOfAny (前方からの探索) LastIndexOfAny (後方からの探索) |
解説へ |
部分文字列を含むかどうかの判定 (部分一致の判定) |
Contains | 解説へ |
部分文字列で始まるかどうかの判定 (前方一致の判定) |
StartsWith | 解説へ |
部分文字列で終わるかどうかの判定 (後方一致の判定) |
EndsWith | 解説へ |
null または空の文字列かどうかの判定 |
IsNullOrEmpty | 解説へ |
null 、空の文字列、または空白のみかどうかの判定 |
IsNullOrWhiteSpace | 解説へ |
文字列が等しいかどうかの判定 | Equals | 解説へ |
等価演算子・不等価演算子 | 解説へ | |
文字列の大小関係の比較 | Compare, CompareTo | 解説へ |
序数による文字列の大小関係の比較 | CompareOrdinal | 解説へ |
文字列操作 | 対応するStringクラスのメソッド | 解説へのリンク |
上記以外のメソッドやここでは扱わない事項・関連する事項に関しては以下を参照してください。
- 文字列の連結や分割、部分文字列の切り出しなど、文字列の加工や編集については文字列の加工・編集を参照してください。
- 大文字小文字の違いなどの文字列の探索・比較時のオプション、カルチャの規則に基づいた比較・ロケール(カルチャ)によって動作が変わる場合とそれに依存しない方法など、文字と文字列の比較規則に関する詳細については文字列と比較オプション・カルチャの並べ替え規則を参照してください。
- Stringクラスでは正規表現などのパターンマッチングによる文字列操作は直接はサポートされません。 正規表現を使った文字列操作については正規表現によるパターンマッチングと文字列操作を参照してください。
- この文章ではUnicode正規形や正規化、サロゲートペアを含む文字列の扱いについては踏み込みません。 そういった要素を含む文字列の処理に関しては別途他のドキュメントを参照してください。
文字列の探索
ここでは文字列の探索などを行うためのメソッドについて見ていきます。
部分文字列の探索 (IndexOf, LastIndexOf)
String.IndexOfメソッドは文字列内にある部分文字列の位置を探索するメソッドで、文字列内にある部分文字列の最初のインデックスを返します。 文字列内に部分文字列がない場合は-1が返されます。
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が返される
}
}
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が返されます。
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"));
}
}
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が返されます。
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'));
}
}
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で指定することができます。 例えば、大文字小文字の違いを無視して部分文字列が一致するかどうかを調べることが出来ます。
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));
}
}
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が返されます。
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'}));
}
}
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メソッドとは逆に後ろから探索を行い、文字列内で見つかった最後の位置を返します。
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'}));
}
}
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が返されます。
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"));
}
}
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メソッドは部分文字列で終わるかどうかを調べるメソッドです。
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"で終わるか
}
}
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で指定することができます。 例えば、大文字小文字の違いを無視して部分文字列が一致するかどうかを調べることができます。
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));
}
}
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以降でのみ使用できます。
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)); // 大文字小文字の違いを無視する
}
}
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
を引数にとるバージョンが用意されています。
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'で終わるか
}
}
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
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'を含むかどうか
}
}
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メソッドを実装したものです。
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'で終わるか
}
}
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
もしくは空文字か、空白文字のみで構成されているかどうかをチェックする静的メソッドです。
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));
}
}
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.IsWhiteSpaceがtrue
となる文字)が空白文字として扱われます。
なお、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;
}
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
同士は等価として扱われます。
文字列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を返します。
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));
}
}
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メソッドは、静的メソッドとしても用意されています。 戻り値はインスタンスメソッドの場合と同じです。
文字列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 |
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));
}
}
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
同士の比較を行っても例外エラーにはなりません)
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がスローされる
}
}
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で指定することができます。 例えば、大文字小文字の違いを無視して文字列の比較を行うことができます。
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));
}
}
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メソッドでは常にカルチャに依存しない比較が行われます。
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]));
}
}
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と異なる型の比較を行おうとしてもコンパイルエラーにはなりません。
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メソッドを使用する必要があります。