mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-14 19:49:15 +08:00
96 lines
3.6 KiB
C#
96 lines
3.6 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Globalization;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Text.RegularExpressions;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace Wox.Plugin.Caculator
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Tries to convert all numbers in a text from one culture format to another.
|
|||
|
/// </summary>
|
|||
|
public class NumberTranslator
|
|||
|
{
|
|||
|
private readonly CultureInfo sourceCulture;
|
|||
|
private readonly CultureInfo targetCulture;
|
|||
|
private readonly Regex splitRegexForSource;
|
|||
|
private readonly Regex splitRegexForTarget;
|
|||
|
|
|||
|
private NumberTranslator(CultureInfo sourceCulture, CultureInfo targetCulture)
|
|||
|
{
|
|||
|
this.sourceCulture = sourceCulture;
|
|||
|
this.targetCulture = targetCulture;
|
|||
|
|
|||
|
this.splitRegexForSource = GetSplitRegex(this.sourceCulture);
|
|||
|
this.splitRegexForTarget = GetSplitRegex(this.targetCulture);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a new <see cref="NumberTranslator"/> - returns null if no number conversion
|
|||
|
/// is required between the cultures.
|
|||
|
/// </summary>
|
|||
|
/// <param name="sourceCulture">source culture</param>
|
|||
|
/// <param name="targetCulture">target culture</param>
|
|||
|
/// <returns></returns>
|
|||
|
public static NumberTranslator Create(CultureInfo sourceCulture, CultureInfo targetCulture)
|
|||
|
{
|
|||
|
bool conversionRequired = sourceCulture.NumberFormat.NumberDecimalSeparator != targetCulture.NumberFormat.NumberDecimalSeparator
|
|||
|
|| sourceCulture.NumberFormat.PercentGroupSeparator != targetCulture.NumberFormat.PercentGroupSeparator
|
|||
|
|| sourceCulture.NumberFormat.NumberGroupSizes != targetCulture.NumberFormat.NumberGroupSizes;
|
|||
|
return conversionRequired
|
|||
|
? new NumberTranslator(sourceCulture, targetCulture)
|
|||
|
: null;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Translate from source to target culture.
|
|||
|
/// </summary>
|
|||
|
/// <param name="input"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public string Translate(string input)
|
|||
|
{
|
|||
|
return this.Translate(input, this.sourceCulture, this.targetCulture, this.splitRegexForSource);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Translate from target to source culture.
|
|||
|
/// </summary>
|
|||
|
/// <param name="input"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public string TranslateBack(string input)
|
|||
|
{
|
|||
|
return this.Translate(input, this.targetCulture, this.sourceCulture, this.splitRegexForTarget);
|
|||
|
}
|
|||
|
|
|||
|
private string Translate(string input, CultureInfo cultureFrom, CultureInfo cultureTo, Regex splitRegex)
|
|||
|
{
|
|||
|
var outputBuilder = new StringBuilder();
|
|||
|
|
|||
|
string[] tokens = splitRegex.Split(input);
|
|||
|
foreach (string token in tokens)
|
|||
|
{
|
|||
|
decimal number;
|
|||
|
outputBuilder.Append(
|
|||
|
decimal.TryParse(token, NumberStyles.Number, cultureFrom, out number)
|
|||
|
? number.ToString(cultureTo)
|
|||
|
: token);
|
|||
|
}
|
|||
|
|
|||
|
return outputBuilder.ToString();
|
|||
|
}
|
|||
|
|
|||
|
private Regex GetSplitRegex(CultureInfo culture)
|
|||
|
{
|
|||
|
var splitPattern = $"((?:\\d|{Regex.Escape(culture.NumberFormat.NumberDecimalSeparator)}";
|
|||
|
if (!string.IsNullOrEmpty(culture.NumberFormat.NumberGroupSeparator))
|
|||
|
{
|
|||
|
splitPattern += $"|{Regex.Escape(culture.NumberFormat.NumberGroupSeparator)}";
|
|||
|
}
|
|||
|
splitPattern += ")+)";
|
|||
|
return new Regex(splitPattern);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|