C#函数将英尺/英寸/米/厘米/毫米的文本输入转换为数字值

问题描述

| 我正在编写一个函数获取速记值并将其转换为标准的数字格式。是否有任何标准代码可以“最佳”转换任意度量文本并将其转换为数字度量(如果文本有效)? 我想我正在寻找类似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();
        }
    }
}