指定した文字列に含まれる値を取得する (Val)
スポンサーリンク
ある文字列を数値に変換する場合は、不正な文字が入っている場合を考慮する必要があります。殆どのキャストでは、不正な文字が入っていると失敗します。(例外が発生する)
VB6 には Val という関数がありました。これは、数値として読み取り可能な部分のみを返すことができます。不正な文字ばかりの場合は、0 を返すことができるので、例外を考慮しなくて良いわけです。
VB.NET では Microsoft.VisualBasic 名前空間配下にある Val メソッドがこれにあたります。これまた、Microsoft.VisualBasic 名前空間配下を使いたくないという方のために自作してみました。指数の考慮があるため、ベタに組むほかありませんでした。8 進数、16 進数の対応は省きました。(言語によって表記方法が違うため)エラー検証でもあまり使う機会は少なくなりましたが、とりあえず紹介しておきます。
サンプルコード
以下にサンプルコードを示します。
J# 全般
import System.*; /******************************************************************************** * * 検証・エラーチェックをサポートした静的クラスです。 * ********************************************************************************/ public final class Validation { #region Val メソッド (+2) /******************************************************************************** * 指定した文字列に含まれる数値を変換して返します。 * * @param stTarget 任意の有効な文字列。 * @return 指定した文字列に含まれる数値。 ********************************************************************************/ public static final double Val(final String stTarget) { // Null 値の場合は 0 を返す if (stTarget == null) { return 0D; } int iCurrent = 0; final int iLength = stTarget.get_Length(); // 評価対象外の文字をスキップする for (iCurrent = 0; iCurrent < iLength; iCurrent++) { char chOne = stTarget.get_Chars(iCurrent); if ((chOne != ' ') && (chOne != ' ') && (chOne != '\t') && (chOne != '\n') && (chOne != '\r')) { break; } } // 終端までに有効な文字が見つからなかった場合は 0 を返す if (iCurrent >= iLength) { return 0D; } boolean bMinus = false; // 先頭にある符号を判定する switch (stTarget.get_Chars(iCurrent)) { case '-': bMinus = true; iCurrent++; break; case '+': iCurrent++; break; } int iValidLength = 0; int iPriod = 0; double dReturn = 0D; boolean bDecimal = false; boolean bShisuMark = false; // 1 文字ずつ有効な文字かどうか判定する while (iCurrent < iLength) { char chCurrent = stTarget.get_Chars(iCurrent); if ((chCurrent == ' ') || (chCurrent == ' ') || (chCurrent == '\t') || (chCurrent == '\n') || (chCurrent == '\r')) { iCurrent++; } else if (chCurrent == '0') { iCurrent++; if ((iValidLength != 0) || bDecimal) { iValidLength++; dReturn = (dReturn * 10) + System.Double.Parse(System.Convert.ToString(chCurrent)); } } else if ((chCurrent >= '1') && (chCurrent <= '9')) { iCurrent++; iValidLength++; dReturn = (dReturn * 10) + System.Double.Parse(System.Convert.ToString(chCurrent)); } else if (chCurrent == '.') { iCurrent++; if (bDecimal) { break; } bDecimal = true; iPriod = iValidLength; } else if ((chCurrent == 'e') || (chCurrent == 'E') || (chCurrent == 'd') || (chCurrent == 'D')) { bShisuMark = true; iCurrent++; break; } else { break; } } int iDecimal = 0; // 小数点が判定された場合 if (bDecimal) { iDecimal = iValidLength - iPriod; } // 指数が判定された場合 if (bShisuMark) { boolean bShisuValid = false; boolean bShisuMinus = false; double dCoef = 0D; // 指数を検証する while (iCurrent < iLength) { char chCurrent = stTarget.get_Chars(iCurrent); if ((chCurrent == ' ') || (chCurrent == ' ') || (chCurrent == '\t') || (chCurrent == '\n') || (chCurrent == '\r')) { iCurrent++; } else if ((chCurrent >= '0') && (chCurrent <= '9')) { dCoef = (dCoef * 10) + System.Double.Parse(System.Convert.ToString(chCurrent)); iCurrent++; } else if (chCurrent == '+') { if (bShisuValid) { break; } bShisuValid = true; iCurrent++; } else if ((chCurrent != '-') || bShisuValid) { break; } else { bShisuValid = true; bShisuMinus = true; iCurrent++; } } // 指数の符号に応じて累乗する if (bShisuMinus) { dCoef += iDecimal; dReturn *= System.Math.Pow(10, - dCoef); } else { dCoef -= iDecimal; dReturn *= System.Math.Pow(10, dCoef); } } else if (bDecimal && (iDecimal != 0)) { dReturn /= System.Math.Pow(10, iDecimal); } // 無限大の場合は 0 を返す if (System.Double.IsInfinity(dReturn)) { return 0D; } // マイナス判定の場合はマイナスで返す if (bMinus) { return -dReturn; } return dReturn; } /******************************************************************************** * 指定した文字に含まれる数値を変換して返します。 * * @param chTarget 任意の有効な文字。 * @return 指定した文字に含まれる数値。 ********************************************************************************/ public static final int Val(final char chTarget) { return (int)Val(System.Convert.ToString(chTarget)); } /******************************************************************************** * 指定したオブジェクトに含まれる数値を変換して返します。 * * @param oTarget 任意の有効なオブジェクト。 * @return 指定したオブジェクトに含まれる数値。 ********************************************************************************/ public static final double Val(final Object oTarget) { if (oTarget != null) { return Val(oTarget.ToString()); } return 0D; } #endregion }
使用例は以下のようになります。
J# 全般
// 不正な文字を含む文字列から数値部分のみを取得する double dValue = Validation.Val(" -10 24 [不正な文字] 512 "); MessageBox.Show(System.Convert.ToString(dValue)); //-1024
関連するリファレンス
準備中です。