佐々木屋

技術的なことから趣味まで色々書きます

文字列分割(Split)の挙動

C#VB.NETでは文字列分割の挙動で若干の違いがあります。これはVB.NET初学者でもよく間違いますので、しっかり覚えておきましょう。
例えば、文字列「lowhogemiddlehogehighhogenone」を「hoge」で分割することを考えます。分割後を列挙した場合、以下のような結果になることが目標です。

low
middle
high
none


VB.NETのみ】String.SplitメソッドとSplit関数の違い

VB.NETではString.SplitメソッドとSplit関数の2種類の方法があります。後者のSplit関数はVB独自の記法でVB6時代から継承された関数です。
普通にSplit関数を利用すれば問題なく分割することができます。

Dim res1 As String() = Split(naiyo, "hoge")
low
middle
high
none

また別の機会にも書きますが、本来VB.NETの環境下において、VB6名残の機能は使用しない方が良いと言われていますので、StringクラスのSplitメソッドで書き換えます。そうすると、結果はどうなるでしょうか。

Dim res1 As String() = naiyo.Split("hoge")
low
ogemiddle
oge
ig

ogenone



本来StringクラスのSplitメソッドは、区切り文字をchar型にする必要があります。それが.NET Framework2.0よりstring型を渡せるようになりましたが、この場合配列で渡す必要があります。しかし、VB.NETの場合はVB6ユーザーへ忖度したため、string型でも配列にする必要性を省いてしまいました。結果、string型の一文字目をchar型と勝手に認識するようにして、最初の「h」のみを区切り文字にしてしまったのです。
そうすると、区切られる文字列に「h」が含まれていると、そこまで区切ってしまいます。上記の場合「high」という単語の「h」に反応してしまった形です。

この場合は以下のようにstring型の配列で渡す必要があります。string型(配列)をSplitメソッドに渡した場合は、StringSplitOptionsオプションを第二引数に入れないとコンパイルエラーになります。

'空要素を排除する場合はStringSplitOptionsにRemoveEmptyEntriesを指定する
Dim res1 As String() = naiyo.Split(New String() {"hoge"}, StringSplitOptions.None)

なお、C#の場合はstring型を引数に渡すことはできませんので、VB.NETのようなおかしな動作になることはありません。

他の方法

char型であれば特に不自由なく分割できますが、例のようにstring型だと配列にしてあげれば問題なく分割できます。
文字列分割は他にもいくつか方法がありますので、予備知識として少し紹介しておきます(基本はString.Splitメソッドで問題ない)。

System.Text.RegularExpression名前空間Regexクラスによる分割

RegexクラスのSplitメソッドでも文字列を分割できます。Stringクラスよりは速度は遅めです。

string[] res1 = System.Text.RegularExpressions.Regex.Split(naiyo, "hoge");
Dim res1 As String() = System.Text.RegularExpressions.Regex.Split(naiyo, "hoge")


ReplaceメソッドとSplitメソッドの合わせ技

文字列に絶対含まれないchar型の文字が簡単に推測できるなら有用な方法です。Replaceメソッドで一旦区切り文字を適当なchar文字に変換した後にSplitメソッドにそのchar文字を渡す方法です。速度は以外と早く、RegexクラスのSplitメソッドより高速です。

string[] res1 = naiyo.Replace("hoge", ",").Split(',')
Dim res1 As String() = naiyo.Replace("hoge", ",").Split(",")


C#のみ】Microsoft.VisualBasic.Strings.Split関数による分割

VBのSplit関数機能を利用して分割する方法です。速度はとてつもなく遅いのでおすすめしません。

string[] res1 = Microsoft.VisualBasic.Strings.Split(naiyo, "hoge");