文字列の中にあるNULLを削除するには?

タグの編集
投稿者 VB2008初心者  (社会人) 投稿日時 2009/3/11 02:01:55
お世話になります。

文字列の中にNULLが有ったら、そのNULLを""(空白:Nothing)に置き換えたいのですが、
NULLかどうかを判定する方法を知りたくて投稿しました。
何方かご教授お願いします。
データベースの場合は、If Not TypeOf SqlReader("TEST-AA") Is DBNull Then
などで判定出来ますが、テキストデータから文字列変数へ格納する場合に判定する時の
やり方が分かりません。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/3/11 02:51:35
ここでいう「文字列の中にあるNULL」とは、以下のどれに相当しますか?

Dim S1 As String = "NULL"
Dim S2 As String = ChrW(0)    'もしくは = vbNullChar 
Dim S3 As String = Nothing
Dim S4 As String = ""    'もしくは = String.Empty 
'Dim S5 As String = その他 


> NULLかどうかを判定する方法を知りたくて投稿しました。
置き換えだけなら存在判定は不要で、常に Replace してしまえば良いかと思います。
Dim newText As String = Replace( 元のテキスト, NULL文字, "")
[NULL文字]の部分は、先の S1~S5 のいずれかの値になるでしょう。
投稿者 VB2008初心者  (社会人) 投稿日時 2009/3/11 06:41:19
魔界の仮面弁士さん 返信がおそくなってしまい申し訳有りませんでした!

>ここでいう「文字列の中にあるNULL」とは、以下のどれに相当しますか?
ブレークポイントで、文字列を表示すると、"" になっています。
そこで、If 文字列 = "" Then 
          ステートメント    'ステップ実行すると、このステートメントは実行されません
        End If
また、 If 文字列 = Nothing Then
          ステートメント    'ステップ実行すると、このステートメントは実行されません
        End If
としてみても、ステートメント は実行されません。
データをテキストファイルに出力して、バイナリダンプしたら、コードが "00"になっているので
Nullだと思っています。

>置き換えだけなら存在判定は不要で、常に Replace してしまえば良いかと思います。
上記のケースでは、NULL文字 は何を指定したら良いのでしょうか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/3/11 07:44:38
> ブレークポイントで、文字列を表示すると、"" になっています。
そのチェック方法では、非可読文字のチェックには向かないかと。

先のコードでいうと「S2」は "" ではありませんが、
表示上は "" であるかのように見えてしまいますから。

S2, S4, S5 のいずれのパターンに相当するのか、再確認してみてください。

その結果、たとえば S2 のパターンだとしたら、
  Dim newText As String = Replace( 元のテキスト, vbNullChar, "")
という記述になるでしょう。


> If 文字列 = Nothing Then
その記述は不自然です。そもそも、
「If 文字列 Is Nothing Then」と
「If 文字列 = Nothing Then」の違いは理解されていますでしょうか。

「S3」の場合、どちらの書き方でも True となりますが、
「S4」の場合、= は True ですが、Is だと False になる事に注意してください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/3/11 09:01:44
> データをテキストファイルに出力して、バイナリダンプしたら、
> コードが "00"になっているので Nullだと思っています。

VB.NET に Null というキーワードは無いので、この場合は vbNullChar ですかね。

ところで、"0000" の 2 バイトではなく
"00" の 1 バイトという事は、Shift_JIS や UTF-8 での保存でしょうか。

テキストファイルにする手法は、Encoding の段階で化ける可能性があるので、
String の中身を厳密に調べる場合には、不向きとされる事があります。


'42 30 00 00 A5 33 3F 00 …… ダンプさせる文字列 
Dim A As String = ChrW(&H3042) & ChrW(&H0000) & ChrW(&H33A5) & ChrW(&H003F)

'82 A0 00 3F 3F …… ChrW(&H33A5) が壊れる 
System.IO.File.WriteAllText("C:\sjis.txt", A, System.Text.Encoding.GetEncoding("Shift_JIS"))

'FF FE 42 30 00 00 A5 33 3F 00 
System.IO.File.WriteAllText("C:\utf16-1.txt", A, System.Text.Encoding.Unicode)

'42 30 00 00 A5 33 3F 00 …… 期待する結果に最も近い 
System.IO.File.WriteAllBytes("C:\utf16-2.txt", System.Text.Encoding.Unicode.GetBytes(A))

'2B 4D 45 49 41 41 44 4F 6C 2D 3F 
System.IO.File.WriteAllText("C:\utf7.txt", A, System.Text.Encoding.UTF7)

'EF BB BF E3 81 82 00 E3 8E A5 3F 
System.IO.File.WriteAllText("C:\utf8_1.txt", A, System.Text.Encoding.UTF8)

'E3 81 82 00 E3 8E A5 3F 
System.IO.File.WriteAllText("C:\utf8_2.txt", A)



文字列(String)の内容をダンプする場合には、個々の文字(Char)を
AscW で数値化する方が良いかも知れません。

Dim S As String = ChrW(&H3042) & ChrW(&H0000) & ChrW(&H33A5) & ChrW(&H003F)
ListBox1.DataSource = S.Select(Function(c) String.Format("{0:x4}:{1}", AscW(C), C)).ToList()


Dim S As String = ChrW(&H3042) & ChrW(&H0000) & ChrW(&H33A5) & ChrW(&H003F)
ListBox1.DataSource = Array.ConvertAll(Of CharInteger)(S.ToCharArray(), AddressOf AscW)
'Array.ForEach(Array.ConvertAll(Of Char, Integer)(S.ToCharArray(), AddressOf AscW), AddressOf Console.WriteLine)