问题描述
|
我正在编写一个函数以获取速记值并将其转换为标准的数字格式。是否有任何标准代码可以“最佳”转换任意度量文本并将其转换为数字度量(如果文本有效)?
我想我正在寻找类似bool TryParseMeasurement(string s,十进制d)的东西。有人知道这样的功能吗?
这是我见过的一些输入值的示例:
英制
6英寸
6英寸
6”
4英尺2英寸
4’2”
4‘2“
3英尺
3’
3’
3英尺
3英尺10英寸
3英尺13英寸(应转换为4英尺1英寸)
公制
1m
1.2m
1.321m
1米
481毫米
解决方法
这是我们很久以前在应用程序中编写的一些代码,当时我们正在做类似的事情。这不是最好的方法,但是您可能能够适应或获得某种起点。
public static class UnitConversion
{
public static string[] lstFootUnits = new string[] {\"foots\",\"foot\",\"feets\",\"feet\",\"ft\",\"f\",\"\\\"\"};
public static string sFootUnit = \"ft\";
public static string[] lstInchUnits = new string[] { \"inches\",\"inchs\",\"inch\",\"in\",\"i\",\"\\\'\" };
public static string sInchUnit = \"in\";
public static string[] lstPoundUnits = new string[] { \"pounds\",\"pound\",\"pnds\",\"pnd\",\"lbs\",\"lb\",\"l\",\"p\" };
public static string sPoundUnit = \"lbs\";
public static string[] lstOunceUnits = new string[] { \"ounces\",\"ounce\",\"ozs\",\"oz\",\"o\" };
public static string sOunceUnit = \"oz\";
public static string[] lstCentimeterUnits = new string[] { \"centimeters\",\"centimeter\",\"centimetres\",\"centimetre\",\"cms\",\"cm\",\"c\"};
public static string sCentimeterUnit = \"cm\";
public static string[] lstKilogramUnits = new string[] { \"kilograms\",\"kilogram\",\"kilos\",\"kilo\",\"kgs\",\"kg\",\"k\" };
public static string sKilogramsUnit = \"kgs\";
/// <summary>
/// Attempt to convert between feet/inches and cm
/// </summary>
/// <param name=\"sHeight\"></param>
/// <returns></returns>
public static string ConvertHeight(string sHeight)
{
if (!String.IsNullOrEmpty(sHeight))
{
sHeight = UnitConversion.CleanHeight(sHeight);
if (sHeight.Contains(UnitConversion.sFootUnit))
{
sHeight = sHeight.Replace(UnitConversion.sFootUnit,\"|\");
sHeight = sHeight.Replace(UnitConversion.sInchUnit,\"|\");
string[] sParts = sHeight.Split(\'|\');
double? dFeet = null;
double? dInches = null;
double dFeetParsed;
double dInchesParsed;
if (sParts.Length >= 2 && double.TryParse(sParts[0].Trim(),out dFeetParsed))
{
dFeet = dFeetParsed;
}
if (sParts.Length >= 4 && double.TryParse(sParts[2].Trim(),out dInchesParsed))
{
dInches = dInchesParsed;
};
sHeight = UnitConversion.FtToCm(UnitConversion.CalculateFt(dFeet ?? 0,dInches ?? 0)).ToString() + \" \" + UnitConversion.sCentimeterUnit;
}
else if (sHeight.Contains(UnitConversion.sCentimeterUnit))
{
sHeight = sHeight.Replace(UnitConversion.sCentimeterUnit,\"|\");
string[] sParts = sHeight.Split(\'|\');
double? dCentimeters = null;
double dCentimetersParsed;
if (sParts.Length >= 2 && double.TryParse(sParts[0].Trim(),out dCentimetersParsed))
{
dCentimeters = dCentimetersParsed;
}
int? iFeet;
int? iInches;
if (UnitConversion.CmToFt(dCentimeters,out iFeet,out iInches))
{
sHeight = (iFeet != null) ? iFeet.ToString() + \" \" + UnitConversion.sFootUnit : \"\";
sHeight += (iInches != null) ? \" \" + iInches.ToString() + \" \" + UnitConversion.sInchUnit : \"\";
sHeight = sHeight.Trim();
}
else
{
sHeight = \"\";
}
}
else
{
sHeight = \"\";
}
}
else
{
sHeight = \"\";
}
return sHeight;
}
/// <summary>
/// Attempt to convert between Kgs and Lbs
/// </summary>
/// <param name=\"sWeight\"></param>
/// <returns></returns>
public static string ConvertWeight(string sWeight)
{
if (!String.IsNullOrEmpty(sWeight))
{
sWeight = UnitConversion.CleanWeight(sWeight);
if (sWeight.Contains(UnitConversion.sKilogramsUnit))
{
sWeight = sWeight.Replace(UnitConversion.sKilogramsUnit,\"|\");
string[] sParts = sWeight.Split(\'|\');
double? dKilograms = null;
double dKilogramsParsed;
if (sParts.Length >= 2 && double.TryParse(sParts[0].Trim(),out dKilogramsParsed))
{
dKilograms = dKilogramsParsed;
}
sWeight = UnitConversion.KgToLbs(dKilograms).ToString(\"#.###\") + \" \" + UnitConversion.sPoundUnit;
}
else if (sWeight.Contains(UnitConversion.sPoundUnit))
{
sWeight = sWeight.Replace(UnitConversion.sPoundUnit,\"|\");
string[] sParts = sWeight.Split(\'|\');
double? dPounds = null;
double dPoundsParsed;
if (sParts.Length >= 2 && double.TryParse(sParts[0].Trim(),out dPoundsParsed))
{
dPounds = dPoundsParsed;
}
sWeight = UnitConversion.LbsToKg(dPounds).ToString(\"#.###\") + \" \" + UnitConversion.sKilogramsUnit;
}
else
{
sWeight = \"\";
}
}
else
{
sWeight = \"\";
}
return sWeight;
}
public static double? CalculateFt(double dFt,double dInch)
{
double? dFeet = null;
if (dFt >= 0 && dInch >= 0 && dInch <= 12)
{
dFeet = dFt + (dInch / 12);
}
return dFeet;
}
public static double KgToLbs(double? dKg)
{
if (dKg == null)
{
return 0;
}
return dKg.Value * 2.20462262;
}
public static double LbsToKg(double? dLbs)
{
if (dLbs == null)
{
return 0;
}
return dLbs.Value / 2.20462262;
}
public static double FtToCm(double? dFt)
{
if (dFt == null)
{
return 0;
}
return dFt.Value * 30.48;
}
public static bool CmToFt(double? dCm,out int? iFt,out int? iInch)
{
if (dCm == null)
{
iFt = null;
iInch = null;
return false;
}
double dCalcFeet = dCm.Value / 30.48;
double dCalcInches = dCalcFeet - Math.Floor(dCalcFeet);
dCalcFeet = Math.Floor(dCalcFeet);
dCalcInches = dCalcInches * 12;
iFt = (int)dCalcFeet;
iInch = (int)dCalcInches;
return true;
}
private static string CleanUnit(string sOriginal,string[] lstReplaceUnits,string sReplaceWithUnit)
{
System.Text.StringBuilder sbPattern = new System.Text.StringBuilder();
foreach (string sReplace in lstReplaceUnits)
{
if (sbPattern.Length > 0)
{
sbPattern.Append(\"|\");
}
sbPattern.Append(sReplace);
}
sbPattern.Insert(0,@\"(^|\\s)(\");
sbPattern.Append(@\")(\\s|$)\");
System.Text.RegularExpressions.Regex rReplace = new System.Text.RegularExpressions.Regex(sbPattern.ToString(),System.Text.RegularExpressions.RegexOptions.IgnoreCase);
sOriginal = rReplace.Replace(sOriginal,sReplaceWithUnit);
/*foreach (string sReplace in lstReplaceUnits)
{
sOriginal = sOriginal.Replace(sReplace,\" \" + sReplaceWithUnit);
}*/
return sOriginal;
}
private static bool StringHasNumbers(string sText)
{
System.Text.RegularExpressions.Regex rxNumbers = new System.Text.RegularExpressions.Regex(\"[0-9]+\");
return rxNumbers.IsMatch(sText);
}
private static string ReduceSpaces(string sText)
{
while (sText.Contains(\" \"))
{
sText = sText.Replace(\" \",\" \");
}
return sText;
}
private static string SeperateNumbers(string sText)
{
bool bNumber = false;
if (!String.IsNullOrEmpty(sText))
{
for (int iChar = 0; iChar < sText.Length; iChar++)
{
bool bIsNumber = (sText[iChar] >= \'0\' && sText[iChar] <= \'9\') ||
(sText[iChar] == \'.\' && iChar < sText.Length - 1 && sText[iChar + 1] >= \'0\' && sText[iChar + 1] <= \'9\');
if (iChar > 0 && bIsNumber != bNumber)
{
sText = sText.Insert(iChar,\" \");
iChar++;
}
bNumber = bIsNumber;
}
}
return sText;
}
public static string CleanHeight(string sHeight)
{
if (UnitConversion.StringHasNumbers(sHeight))
{
sHeight = SeperateNumbers(sHeight);
sHeight = CleanUnit(sHeight,UnitConversion.lstFootUnits,UnitConversion.sFootUnit);
sHeight = CleanUnit(sHeight,UnitConversion.lstInchUnits,UnitConversion.sInchUnit);
sHeight = CleanUnit(sHeight,UnitConversion.lstCentimeterUnits,UnitConversion.sCentimeterUnit);
sHeight = SeperateNumbers(sHeight);
sHeight = ReduceSpaces(sHeight);
}
else
{
sHeight = \"\";
}
return sHeight;
}
public static string CleanWeight(string sWeight)
{
if (UnitConversion.StringHasNumbers(sWeight))
{
sWeight = SeperateNumbers(sWeight);
sWeight = CleanUnit(sWeight,UnitConversion.lstOunceUnits,UnitConversion.sOunceUnit);
sWeight = CleanUnit(sWeight,UnitConversion.lstPoundUnits,UnitConversion.sPoundUnit);
sWeight = CleanUnit(sWeight,UnitConversion.lstKilogramUnits,UnitConversion.sKilogramsUnit);
sWeight = SeperateNumbers(sWeight);
sWeight = ReduceSpaces(sWeight);
}
else
{
sWeight = \"\";
}
return sWeight;
}
}
, 为此目的,应该很好地为您构建字符串的扩展方法。构建扩展方法时,会将新的函数调用附加到现有类。在此方法中,我们将方法附加到\'string \'类,该方法返回双精度值,因为给定英制值中的毫米数表示可以根据您提供的示例来解析该值。
using System;
using System.Text;
namespace SO_Console_test
{
static class ConversionStringExtensions
{
//this is going to be a simple example you can
//fancy it up a lot...
public static double ImperialToMetric(this string val)
{
/*
* With these inputst we want to total inches.
* to do this we want to standardize the feet designator to \'f\'
* and remove the inch designator altogether.
6 inches
6in
6”
4 feet 2 inches
4’2”
4 ‘ 2 “
3 feet
3’
3 ‘
3ft
3ft10in
3ft 13in (should convert to 4’1”) ...no,should convert to 49 inches,then to metric.
*/
//make the input lower case and remove blanks:
val = val.ToLower().Replace(\" \",string.Empty);
//make all of the \'normal\' feet designators to \"ft\"
string S = val.Replace(\"\\\'\",\"f\").Replace(\"feet\",\"f\").Replace(\"ft\",\"f\").Replace(\"foot\",\"f\").Replace(\"‘\",\"f\").Replace(\"’\",\"f\");
//and remove any inch designator
S = S.Replace(\"\\\"\",string.Empty).Replace(\"inches\",string.Empty).Replace(\"inch\",string.Empty).Replace(\"in\",string.Empty).Replace(\"“\",string.Empty).Replace(\"”\",string.Empty);
//finally we have to be certain we have a number of feet,even if that number is zero
S = S.IndexOf(\'f\') > 0 ? S : \"0f\" + S;
//now,any of the inputs above will have been converted to a string
//that looks like 4 feet 2 inches => 4f2
string[] values = S.Split(\'f\');
int inches = 0;
//as long as this produces one or two values we are \'on track\'
if (values.Length < 3)
{
for (int i = 0; i < values.Length; i++)
{
inches += values[i] != null && values[i] != string.Empty ? int.Parse(values[i]) * (i == 0 ? 12 : 1) : 0 ;
}
}
//now inches = total number of inches in the input string.
double result = inches * 25.4;
return result;
}
}
}
到位后,“ ImperialToMetric()\”成为任何字符串的方法,并且可以在引用包含类“ 2”的扩展名的任何地方调用。您可以像这样使用它:
namespace SO_Console_test
{
class Program
{
static void Main(string[] args)
{
showConversion();
Console.ReadLine();
}
private static void showConversion()
{
//simple start:
Console.WriteLine(\"6ft 2\\\"\".ImperialToMetric().ToString() + \" mm\");
//more robust:
var Imperials = new List<string>(){\"6 inches\",\"6in\",\"6”\",\"4 feet 2 inches\",\"4’2”\",\"4 ‘ 2 “\",\"3 feet\",\"3’\",\"3 ‘\",\"3ft\",\"3ft10in\",\"3ft 13in\"};
foreach (string imperial in Imperials)
{
Console.WriteLine(imperial + \" converted to \" + imperial.ImperialToMetric() + \" millimeters\");
}
}
}
显然,此时打到\"Fred\".ImperialToMetric
的声音不好。您将需要进行错误处理,也许还需要一些选择来转动1234毫米1.234公里,等等。但是一旦将其冲洗掉,您便可以使用一种方法在任何地方使用。
, using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
double km,m,f,i,cm;
Console.WriteLine(\"The distance between karachi and lahore in (kilometer)km is=\");
km = Convert.ToInt32(Console.ReadLine());
m = km * 1000;
Console.WriteLine(\"The distance between karachi and lahore in meter(m) is=\"+m);
f = km * 3280.84;
Console.WriteLine(\"The distance between karachi and lahore in feet(f) is=\"+f);
i = km * 39370.1;
Console.WriteLine(\"The distance between karachi and lahore in inches(i) is=\"+i);
cm = m * 100;
Console.WriteLine(\"The distance between karachi and lahore in centimeter(cm) is=\"+cm);
Console.ReadLine();
}
}
}