是否有任何C#庫在那裏提供相同類型的功能谷歌當你鍵入查詢如「13英里743碼米」它會返回「21 600米」(例如)。C#距離(英里/公里/英寸)字符串解析庫
我想要做的是給函數字符串部分13 miles 743 yards
,它吐出一個以米爲單位給定距離的int/double。它需要能夠處理所有的單位輸入類型(公里/米/弗朗/英里/碼/ ...),但輸出只能以米爲單位。
編寫我自己的代碼並不難,但只要有一個測試過的庫準備好就可以了。
是否有任何C#庫在那裏提供相同類型的功能谷歌當你鍵入查詢如「13英里743碼米」它會返回「21 600米」(例如)。C#距離(英里/公里/英寸)字符串解析庫
我想要做的是給函數字符串部分13 miles 743 yards
,它吐出一個以米爲單位給定距離的int/double。它需要能夠處理所有的單位輸入類型(公里/米/弗朗/英里/碼/ ...),但輸出只能以米爲單位。
編寫我自己的代碼並不難,但只要有一個測試過的庫準備好就可以了。
我找不到任何答案,所以我建立了自己的:)這裏唯一真正的「魔術」是從原始字符串中獲取值/單位組的正則表達式。從那裏它是簡單的分數/數字解析,然後計算出每個單位代表多少米。我還沒有測試過這麼多,所以請讓我知道,如果你發現改進或錯誤(下面的代碼應該拋出一個異常,當它無法處理的情況下)。
它不會處理愚蠢的用戶輸入,但提供每個部分的格式是「[數字] [單位]」我認爲它應該工作正常。無論如何,如果輸入不符合(例如,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('/'))
{
// If the value contains /, we need to work out the fraction
string[] splitVal = fraction.Split('/');
if (splitVal.Length != 2)
{
ScrewUp(fraction, "splitVal.Length");
}
// Turn the fraction into decimal
value = double.Parse(splitVal[0])/double.Parse(splitVal[1]);
}
else
{
// Otherwise it's a simple parse
value = double.Parse(fraction);
}
return value;
}
public static double ExtractDistance(string distAsString)
{
double distanceInMeters = 0;
/* This will have a match per unit type.
* e.g., the string "1 1/16 Miles 3/4 Yards" would have 2 matches
* being "1 1/16 Miles", "3/4 Yards". Each match will then have 4
* groups in total, with group 3 being the raw value and 4 being the
* raw unit
*/
var matches = Regex.Matches(distAsString, @"(([\d]+[\d\s\.,/]*)\s([A-Za-z]+[^\s\d]))");
foreach (Match match in matches)
{
// If groups != 4 something went wrong, we need to rethink our regex
if (match.Groups.Count != 4)
{
ScrewUp(distAsString, "match.Groups.Count");
}
string valueRaw = match.Groups[2].Value;
string unitRaw = match.Groups[3].Value;
// Firstly get the value
double value = 0;
if (valueRaw.Contains(' '))
{
// If the value contains /, we need to work out the fraction
string[] splitVal = valueRaw.Split(' ');
if (splitVal.Length != 2)
{
ScrewUp(distAsString, "splitVal.Length");
}
// Turn the fraction into decimal
value = ConvertFraction(splitVal[0]) + ConvertFraction(splitVal[1]);
}
else
{
value = ConvertFraction(valueRaw);
}
// Now work out based on the unit type
// Clean up the raw unit string
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 + ")");
}
享受!我希望有人在那裏發現這有用。請留下意見/建議。
編輯:增加了,
的正則表達式的字符串處理1,300 meters
樣式格式
做到這一點的一種方法是向谷歌提出請求,然後解析返回的HTML。
更新:這將是非常低效,但他們已經照顧到你的辛勤工作。爲了使這個工作,你必須使英語(爲你的例子)語言分析器接受輸入,去掉無意義的單詞/符號(如和和逗號),找到值(13和743),找到單位(英里,碼和米)找到操作員(進入或到)。之後,您必須確保它具有語法意義。你還必須保留一個轉換表(不難)。
這絕對有可能,但它是一堆工作,我不確定是否已經存在(除谷歌以外)。有太多的角落案例你必須擔心。讓圖書館做這項工作將是一件有趣的工作,但很難抓住所有案例。
的更容易的解決辦法是給他們離散的控制採取語言解析出
是...很聰明.. – 2010-11-10 00:23:16
我不會說我想分析每次調用一個在線服務的距離'聰明'。特別是如果你想離線解析距離,這是完全合理的。 – mike 2010-11-10 00:32:51
好吧,這不是真的很聰明,但它的工作原理。他們已經關注語言解析 – 2010-11-10 01:15:09
這裏是一個單位轉換庫。沒有所有的測量(弗隆!?)你想要的單位,但看起來有最:
http://www.codeproject.com/KB/library/Measurement_Conversion.aspx
沒有找到與字符串解析什麼。老實說,這似乎是一個容易出錯的方式來獲得輸入。試想一下:
所有意味着同樣的事情,即使你給出了關於如何寫作的痛苦具體指示e出他們的字符串,他們可能會做他們對他們有意義的東西...
如果你想進入什麼人試圖說,那麼你真的可能會更好地與谷歌去。否則,你可能會嘗試填入特定的輸入。
我認爲你是過度複雜的問題。輸出只能是米,所以字符串的「米」或「米」部分不存在。剝離「和」絨毛自然也是如此。我沒有選擇輸入,我只是需要將這些半井形成的字符串解析成距離。如果我有選擇,我不會問這個問題:)而解決問題的每種方法都會有錯誤,只有這麼多才能做到。如果字符串格式不正確,那只是運氣不好,解析會失敗。 – mike 2010-11-11 08:35:06
只需注意,我只是在過去一小時內完成了編碼。我將在接下來的日子裏對它進行更徹底的測試,但是如果其他人發現我沒有發現的錯誤,我們會在這裏進行測試。如果發現任何錯誤,我會更新這個答案。 – mike 2010-11-11 08:44:16