おそらく、優先順に指定されたルールのリストを設定するでしょう。このようにして、優先順位に従ってルールをプラグインできます。次に、正しいルールを返す正規表現の一致に基づいてリストを解析できます。
簡単なプロトタイプは、次のように非常に簡単にセットアップできます。
public class FormatRule
{
public string Pattern { get; set; }
public CultureInfo Culture { get; set; }
public FormatRule(string pattern, CultureInfo culture)
{
Pattern = pattern;
Culture = culture;
}
}
ルールを優先順に保存するために使用される FormatRule のリスト:
List<FormatRule> Rules = new List<FormatRule>()
{
/* Add rules in order of precedence specifying a culture
* that can handle the pattern, I've chosen en-US and fr-FR
* for this example, but equally any culture could be swapped
* in for various formats you may need to use */
new FormatRule(@"^0.\d+$", CultureInfo.GetCultureInfo("en-US")),
new FormatRule(@"^0,\d+$", CultureInfo.GetCultureInfo("fr-FR")),
new FormatRule(@"^[1-9]+.\d{4,}$", CultureInfo.GetCultureInfo("en-US")),
new FormatRule(@"^[1-9]+,\d{4,}$", CultureInfo.GetCultureInfo("fr-FR")),
new FormatRule(@"^-?[1-9]{1,3}(,\d{3,})*(\.\d*)?$", CultureInfo.GetCultureInfo("en-US")),
new FormatRule(@"^-?[1-9]{1,3}(.\d{3,})*(\,\d*)?$", CultureInfo.GetCultureInfo("fr-FR")),
/* The default rule */
new FormatRule(string.Empty, CultureInfo.CurrentCulture)
}
その後、適用する正しいルールを探してリストを反復できるはずです。
public CultureInfo FindProvider(string numberString)
{
foreach(FormatRule rule in Rules)
{
if (Regex.IsMatch(numberString, rule.Pattern))
return rule.Culture;
}
return Rules[Rules.Count - 1].Culture;
}
この設定により、ルールを簡単に管理し、何らかの方法で処理する必要がある場合に優先順位を設定できます。また、異なるカルチャを指定して、ある形式をある方法で処理し、別の形式を別の方法で処理することもできます。
public float ParseValue(string valueString)
{
float value = 0;
NumberStyles style = NumberStyles.Any;
IFormatProvider provider = FindCulture(valueString).NumberFormat;
if (float.TryParse(numberString, style, provider, out value))
return value;
else
throw new InvalidCastException(string.Format("Value '{0}' cannot be parsed with any of the providers in the rule set.", valueString));
}
最後に、ParseValue() メソッドを呼び出して、持っている文字列値を float に変換します。
string numberString = "-123,456.78"; //Or "23.457.234,87"
float value = ParseValue(numberString);
辞書を使用して、追加の FormatRule クラスを節約することもできます。概念は同じです...LINQを使用してクエリを実行しやすくするため、例でリストを使用しました。また、必要に応じて、single、double、または decimal に使用した float 型を簡単に置き換えることができます。