指定した文字列に含まれる値を取得する (Val)
スポンサーリンク
ある文字列を数値に変換する場合は、不正な文字が入っている場合を考慮する必要があります。殆どのキャストでは、不正な文字が入っていると失敗します。(例外が発生する)
VB6 には Val という関数がありました。これは、数値として読み取り可能な部分のみを返すことができます。不正な文字ばかりの場合は、0 を返すことができるので、例外を考慮しなくて良いわけです。
VB.NET では Microsoft.VisualBasic 名前空間配下にある Val メソッドがこれにあたります。これまた、Microsoft.VisualBasic 名前空間配下を使いたくないという方のために自作してみました。指数の考慮があるため、ベタに組むほかありませんでした。8 進数、16 進数の対応は省きました。(言語によって表記方法が違うため)エラー検証でもあまり使う機会は少なくなりましたが、とりあえず紹介しておきます。
サンプルコード
以下にサンプルコードを示します。
VB.NET 全般
Option Strict On Public NotInheritable Class Validation #Region " Val メソッド (+2) " ''' ----------------------------------------------------------------------------- ''' <summary> ''' 指定した文字列に含まれる数値を変換して返します。</summary> ''' <param name="stTarget"> ''' 任意の有効な文字列。</param> ''' <returns> ''' 指定した文字列に含まれる数値。<returns> ''' ----------------------------------------------------------------------------- Public Shared Overloads Function Val(ByVal stTarget As String) As Double ' Null 値の場合は 0 を返す If stTarget Is Nothing Then Return 0# End If Dim iCurrent As Integer Dim iLength As Integer = stTarget.Length ' 評価対象外の文字をスキップする For iCurrent = 0 To iLength Select Case stTarget.Chars(iCurrent) Case " "c, " "c, ControlChars.Tab, ControlChars.Cr, ControlChars.Lf Case Else Exit For End Select Next iCurrent ' 終端までに有効な文字が見つからなかった場合は 0 を返す If iCurrent >= iLength Then Return 0# End If Dim bMinus As Boolean ' 先頭にある符号を判定する Select Case stTarget.Chars(iCurrent) Case "-"c bMinus = True iCurrent += 1 Case "+"c iCurrent += 1 End Select Dim iValidLength As Integer Dim iPriod As Integer Dim dReturn As Double Dim bDecimal As Boolean Dim bShisuMark As Boolean ' 1 文字ずつ有効な文字かどうか判定する While (iCurrent < iLength) Dim chCurrent As Char = stTarget.Chars(iCurrent) Select Case chCurrent Case " "c, " "c, ControlChars.Tab, ControlChars.Cr, ControlChars.Lf iCurrent += 1 Case "0"c iCurrent += 1 If iValidLength <> 0 OrElse bDecimal Then iValidLength += 1 dReturn = (dReturn * 10) + Double.Parse(chCurrent.ToString()) End If Case "1"c To "9"c iCurrent += 1 iValidLength += 1 dReturn = (dReturn * 10) + Double.Parse(chCurrent.ToString()) Case "."c iCurrent += 1 If bDecimal Then Exit While End If bDecimal = True iPriod = iValidLength Case "e"c, "E"c, "d"c, "D"c bShisuMark = True iCurrent += 1 Exit While Case Else Exit While End Select End While Dim iDecimal As Integer ' 小数点が判定された場合 If bDecimal Then iDecimal = iValidLength - iPriod End If ' 指数が判定された場合 If bShisuMark Then Dim bShisuValid As Boolean Dim bShisuMinus As Boolean Dim dCoef As Double ' 指数を検証する While (iCurrent < iLength) Dim chCurrent As Char = stTarget.Chars(iCurrent) If (chCurrent = " "c) OrElse (chCurrent = " "c) OrElse (chCurrent = ControlChars.Tab) OrElse (chCurrent = ControlChars.Cr) OrElse (chCurrent = ControlChars.Lf) Then iCurrent += 1 ElseIf (chCurrent >= "0"c) AndAlso (chCurrent <= "9"c) Then dCoef = (dCoef * 10) + Double.Parse(chCurrent.ToString()) iCurrent += 1 ElseIf chCurrent = "+"c Then If bShisuValid Then Exit While End If bShisuValid = True iCurrent += 1 ElseIf (chCurrent <> "-"c) OrElse (bShisuValid) Then Exit While Else bShisuValid = True bShisuMinus = True iCurrent += 1 End If End While ' 指数の符号に応じて累乗する If bShisuMinus Then dCoef += iDecimal dReturn *= System.Math.Pow(10, - dCoef) Else dCoef -= iDecimal dReturn *= System.Math.Pow(10, dCoef) End If ElseIf (bDecimal) AndAlso (iDecimal <> 0) Then dReturn /= System.Math.Pow(10, iDecimal) End If ' 無限大の場合は 0 を返す If Double.IsInfinity(dReturn) Then Return 0# End If ' マイナス判定の場合はマイナスで返す If bMinus Then Return -dReturn End If Return dReturn End Function ''' ----------------------------------------------------------------------------- ''' <summary> ''' 指定した文字に含まれる数値を変換して返します。</summary> ''' <param name="chTarget"> ''' 任意の有効な文字。</param> ''' <returns> ''' 指定した文字に含まれる数値。<returns> ''' ----------------------------------------------------------------------------- Public Shared Overloads Function Val(ByVal chTarget As Char) As Integer Return CType(Val(chTarget.ToString()), Integer) End Function ''' ----------------------------------------------------------------------------- ''' <summary> ''' 指定したオブジェクトに含まれる数値を変換して返します。</summary> ''' <param name="oTarget"> ''' 任意の有効なオブジェクト。</param> ''' <returns> ''' 指定したオブジェクトに含まれる数値。<returns> ''' ----------------------------------------------------------------------------- Public Shared Overloads Function Val(ByVal oTarget As Object) As Double If Not oTarget Is Nothing Then Return Val(oTarget.ToString()) End If Return 0# End Function #End Region End Class
使用例は以下のようになります。
VB.NET 全般
' 不正な文字を含む文字列から数値部分のみを取得する Dim dValue As Double = Validation.Val(" -10 24 [不正な文字] 512 "); MessageBox.Show(dValue.ToString()); '-1024
関連するリファレンス
準備中です。