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

Posted

技术标签:

【中文标题】C#函数将英尺/英寸/米/厘米/毫米的文本输入转换为数值【英文标题】:C# function to convert text input of feet/inches/meters/centimeters/millimeters into numeric values 【发布时间】:2011-09-03 17:05:19 【问题描述】:

我正在编写一个函数来获取速记值并将它们转换为标准化的数字格式。是否有任何标准代码可以对任意测量文本进行“最佳”转换并将其转换为数字测量(如果文本有效)?

我想我正在寻找类似 bool TryParseMeasurement(string s, out decimal d) 的东西。有人知道这样的功能吗?

这是我见过的一些输入值的示例:

帝国

6 英寸 6 英寸 6” 4 英尺 2 英寸 4’2” 4‘2” 3 英尺 3' 3' 3 英尺 3ft10in 3 英尺 13 英寸(应转换为 4 英尺 1 英寸)

公制

1m 1.2m 1.321m 1米 481mm

【问题讨论】:

【参考方案1】:

这是我们很久以前在应用程序中编写的一些代码,我们在其中做类似的事情。这不是最好的,但您可能能够适应,或获得某种起点。

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;
    

【讨论】:

将我的偏好切换为您的方法;很干净,谢谢! 难道你没有一个错误,你列出 ' 表示英寸和 " 表示英尺,而实际符号相反吗?【参考方案2】:

为此目的构建字符串的扩展方法应该会为您提供很好的服务。当你构建一个扩展方法时,你将一个新的函数调用附加到一个现有的类。在此,我们将向“字符串”类附加一个方法,该方法返回一个双精度值,作为给定英制值的毫米数,前提是可以根据您提供的示例解析该值。

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()”就变成了任何字符串的方法,并且可以在任何引用包含类ConversionStringExtensions的扩展名的地方调用。你可以像这样使用它:

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 公里等,但是一旦您将其清除,您就有一种方法可以在您选择的任何地方使用。

【讨论】:

好东西!我会试试这个。 你好@Cos Callis & TedSpence,请问你有 MetricToImperial 的功能吗? 如果值为 3ft 3.75 或 3ft 3/4 那么如何将此值转换为公制?有什么建议吗?【参考方案3】:
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();
        
    

【讨论】:

我(owais ahmned)用c#做了一个非常简单的程序。希望你很容易理解。【参考方案4】:

我写了一个字符串的扩展,只是为了发现这里已经有一个解决方案:) 唯一要做的就是将“feet”、“ft”、“'”替换为“'”和“inches” , "inch", "in", """, "\"" 到 "''"。

using System;

namespace CustomExtensions

    public static class StringExtension
    
        const float mPerFeet = 30.48f / 100;
        const float mPerInch = 2.54f / 100;

        // input options:
        // 5'
        // 5'6''
        // 18''
        // 24''
        // 5'6
        // 5 ' 6 ''
        // 5' 6''
        // corner cases:
        // '' will return 0
        // 5''6'' will interpret as 5'6''
        // 5'6' will interpret as 5'6''
        // 6 will interpret as 6''
        // 6''' will interpret as 6''
        public static float MetersFromFeetInches(this string feetInches)
        
            float feet = 0;
            float inches = 0;
            string[] separators = new string[]  "'", "''", " " ;
            string[] subs = feetInches.Split(separators, StringSplitOptions.RemoveEmptyEntries);
            if (subs.Length == 1)
            
                if (feetInches.Trim().EndsWith("''"))
                
                    float.TryParse(subs[0], out inches);
                
                else if (!feetInches.Trim().EndsWith("''") && !feetInches.Trim().EndsWith("'"))
                
                    float.TryParse(subs[0], out inches);
                
                else
                
                    float.TryParse(subs[0], out feet);
                
            
            else if (subs.Length > 1)
            
                float.TryParse(subs[0], out feet);
                float.TryParse(subs[1], out inches);
            
            return feet * mPerFeet + inches * mPerInch;
        
    

【讨论】:

你好。您的答案不支持公制单位,并且需要事先处理英制单位的字符串。您能否调整您的答案以支持这些案例?

以上是关于C#函数将英尺/英寸/米/厘米/毫米的文本输入转换为数值的主要内容,如果未能解决你的问题,请参考以下文章

HUST 1583 长度单位

将米转换为英尺到英寸c ++?

基本长度单位。

厘米换算英尺英寸

c++编程问题,输入你的身高(单位是cm),转换成英尺和英寸显示。

PAT-厘米换算英尺英寸