Хотя синтаксический разбор строк может быть немного быстрее, все это, безусловно, можно сделать с помощью регулярных выражений.Решение, использующее регулярное выражение для синтаксического анализа строки и словарь для выбора коэффициента преобразования, но которое по сути совпадает с ответом @Marco с некоторыми улучшениями в функциональном отношении, будет:
public double ConvertMeasure(string measure)
{
var re = new Regex(@"(?i)(?<value>-?[\d.]+)\s*(?<multiplier>[munp]?)\s*(?<unit>[avw]*)");
var conversionFactors = new Dictionary<string, double> {
{ "", 1 },
{ "m", 1E3 },
{ "u", 1E6 },
{ "n", 1E9 },
{ "p", 1E12 } };
var m = re.Match(measure);
double value = Convert.ToDouble(m.Groups["value"].Value);
return value / conversionFactors[m.Groups["multiplier"].Value.ToLower()];
}
Это игнорируетрегистр строки и игнорирует пробел (включая вкладки, которые могут возникнуть, если кто-то будет вырезать и вставить значение вместо его ввода) между числом и множителем и единицей, но не игнорирует пробел внутри «числа»(то есть, 1.234 mA
в порядке, но 1.2 34 mA
не должно быть в порядке IMO, но анализируется как 1.234
с помощью решения @ Marco - просто будьте осторожны: D).Кроме того, он все равно будет работать, если кто-то случайно вставит перед номером дополнительные нечисловые символы, такие как =
или окружающий набор скобок.
Конечно, ни одно из написанных решений не вернет фактическоеединица в любом случае.Я предполагаю, что, поскольку вы планировали разрешить «m», «u» и т. Д. (Без единицы измерения), у вас есть нечто похожее на текстовое поле с «Amps» или «Amperes» рядом с ним и вы хотите, чтобы кто-товведите любой из 1.3
1.3A
, 1.3 u
или 1.3 uA
и т. д. Таким образом, вы знаете, что такое базовый блок - это решение обеспечит функциональность преобразования и проигнорирует фактический блок.
класс символов [avw]
в регулярном выражении указывает, какие единицы разрешены (в данном случае a
, v
или w
).Если вы хотите, чтобы кто-то случайно не поместил 1.234 mV
в поле, которое ожидает Amps, вы можете изменить функцию, чтобы она принимала строковый параметр «AllowedUnits» (например, a
или v
), а затем вставьте этот параметр в регулярное выражение.вместо avw
, таким образом:
var re = new Regex(@"(?i)(?<value>-?[\d.]+)\s*(?<multiplier>[munp]?)\s*(?<unit>[" + AllowedUnits + @"]*)");
... затем передайте "a"
в любое преобразование для ампер или "v"
в любое преобразование для вольт и т. д.
Я не проверял это, но я думаю, что решение @ Marco сломается, если нет единицы (например, если строка имеет только m
, u
, n
или p
вместо mA
, ua
, nV
и т. Д.).Я верю, что это урезает юнит, потому что обрезает последний символ.Если есть только один символ (например, u
), он потеряет эти данные!Мое решение будет работать не только независимо от устройства, но даже если вы захотите позже поддерживать больше модулей, таких как Hz
, mol
или cd
, хотя родинки и канделы могут быть не такими распространенными винженерный контекст ...
Удачи и веселья!