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