I could not find the answer to this question, so I created my own :) The only real "magic" here is the expression "Regular Expression" to capture groups of values โโ/ units from the original string. A simple fraction / number is scrolled from there, and then the number of meters of each unit is calculated. I have not tested this at all, so please let me know if you find improvements or bugs (the code below should throw an exception if it cannot handle the situation).
, , "[] []". , . , (, 12/32/43 1.43.3.2.44 ) . , , , 1 kilometer and 10 miles ( and). , , .
,
var a = ExtractDistance("1 1/16 Miles 3/4 yards");
var b = ExtractDistance("02234890234.853 meters");
var c = ExtractDistance("1.8 miles 3.2 furlong");
var d = ExtractDistance("1 kilometer");
var e = ExtractDistance("1/16 Miles");
:
private static Dictionary<string, double> _DistanceLookup = new Dictionary<string, double>()
{
{"mile", 1609.344},
{"furlong", 201.168},
{"yard", 0.9144},
{"inch", 0.0254},
{"foot", 0.3048},
{"feet", 0.3048},
{"kilometer", 1000},
{"kilometre", 1000},
{"metre", 1},
{"meter", 1},
{"centimeter", 0.01},
{"centimetre", 0.01},
{"millimeter", 0.001},
{"millimetre", 0.001},
};
private static double ConvertFraction(string fraction)
{
double value = 0;
if (fraction.Contains('/'))
{
string[] splitVal = fraction.Split('/');
if (splitVal.Length != 2)
{
ScrewUp(fraction, "splitVal.Length");
}
value = double.Parse(splitVal[0]) / double.Parse(splitVal[1]);
}
else
{
value = double.Parse(fraction);
}
return value;
}
public static double ExtractDistance(string distAsString)
{
double distanceInMeters = 0;
var matches = Regex.Matches(distAsString, @"(([\d]+[\d\s\.,/]*)\s([A-Za-z]+[^\s\d]))");
foreach (Match match in matches)
{
if (match.Groups.Count != 4)
{
ScrewUp(distAsString, "match.Groups.Count");
}
string valueRaw = match.Groups[2].Value;
string unitRaw = match.Groups[3].Value;
double value = 0;
if (valueRaw.Contains(' '))
{
string[] splitVal = valueRaw.Split(' ');
if (splitVal.Length != 2)
{
ScrewUp(distAsString, "splitVal.Length");
}
value = ConvertFraction(splitVal[0]) + ConvertFraction(splitVal[1]);
}
else
{
value = ConvertFraction(valueRaw);
}
unitRaw = unitRaw.ToLower().Trim().TrimEnd('s');
if (!_DistanceLookup.ContainsKey(unitRaw))
{
ScrewUp(distAsString, "unitRaw");
}
distanceInMeters += value * _DistanceLookup[unitRaw];
}
return distanceInMeters;
}
private static void ScrewUp(string val, string prop)
{
throw new ArgumentException("Extract distance screwed up on string [" + val + "] (bad " + prop + ")");
}
! , - . , /.
EDIT: โโ , 1,300 meters