2011-05-23 151 views
0

以下方法是否有更好,更优雅的解决方案?有没有更好的方法来编写下面的方法?

预期输入格式:

8 h 13 m 

预期输出格式:

8.13 

我的代码:

private string FormatHours(string value) 
{ 
    //Example: (Input = 10 h 53 m) (Output = 10.53) 
    var timeValues = Regex.Split(value, @"[\shm]", RegexOptions.IgnoreCase).Where(s => !string.IsNullOrEmpty(s)).ToArray(); 
    return ((timeValues != null) && (timeValues.Length == 2)) ? string.Format(@"{0:hh}.{1:mm}", timeValues[0], timeValues[1]) : null; 
} 
+0

“我想发送电子邮件 - 我该怎么办 - 使用LINQ”这种问题。显然,LINQ已经来拯救世界...... – 2011-05-23 15:11:53

+0

好的,LINQ已经从标题中删除。看起来我所需要的只是在正则表达式中稍微改进,这也将消除LINQ开销。 – bzsparks 2011-05-23 15:30:16

回答

3

我觉得Regex.Split是矫枉过正这里。普通的旧Match会给你你想要什么:

private static string FormatHours(string value) 
{ 
    Match m = Regex.Match(value, @"^(?<hours>\d{1,2}) h (?<minutes>\d{1,2}) m$"); 
    if (m.Success) 
    { 
     int hours = int.Parse(m.Groups["hours"].Value); 
     int minutes = int.Parse(m.Groups["minutes"].Value); 
     if (hours >= 0 && hours < 24 && minutes >= 0 && minutes < 60) 
      return string.Concat(hours, ".", minutes); 
    } 
    return null; 
} 
+0

您忘记了模式末尾的'm' – abatishchev 2011-05-23 15:25:09

+0

谢谢,这很好。它也消除了LINQ开销,非常好。 – bzsparks 2011-05-23 15:49:37

+0

@abatischev:oops :)现在修复。 – Juliet 2011-05-23 15:59:56

4

有什么理由不使用以下?

value.Replace(" h ",".").Replace(" m",string.Empty) 
+0

唯一的原因是它不会在意外输入时返回'null'。 – Guffa 2011-05-23 15:11:01

+0

如果这是必需的,那么你既可以处理调用代码中的null,也可以抛出更有意义的异常,并进一步检查有效的小时数和分钟数(<60) – Kaido 2011-05-23 15:16:10

+0

不,我说它*不会*返回null,它将返回一个未更改或部分更改的字符串。原始代码也会进行一定程度的验证,如果无法解析输入,则返回'null'。此外,原始代码还将处理“8h13m”和“8h 13m”等输入。 – Guffa 2011-05-23 15:47:56

0

我能想到的唯一的事情是,如果timeValuesnull调用ToArray()会抛出

private string FormatHours(string value) 
    { 
     var timeValues = Regex.Split(value, @"[\shm]", RegexOptions.IgnoreCase).Where(s => !string.IsNullOrEmpty(s)); 

     if (timeValues == null || timeValues.Count() != 2) 
      return null; 

     string[] arr = timeValues.ToArray(); 
     return string.Format(@"{0:hh}.{1:mm}", arr[0], arr[1]); 
    } 
0

表达:

^(\d{1,2}) h (\d{1,2}) m$ 

代码:

var input = "8 h 13 m"; 

var regex = new Regex(@"^(\d{1,2}) h (\d{1,2}) m$", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
var match = regex.Match(input); 
if (!match.Success) throw new Exception(); 
int h = Int32.Parse(match.Groups[1].Value); 
int m = Int32.Parse(match.Groups[2].Value); 

var output = String.Format("{0}.{1}", h, m); 

// or to be sure that that's the realistic numbers 
var today = DateTime.Now; 
var output2 = new DateTime(today.Year, today.Month, today.Day, h, m, 0).ToString("hh.mm"); 
0

LINQ是不是真的适合你的问题。在一个稍微不同的方式比你正在做使用正则表达式是什么,我会做:

String FormatHours(String value) { 
    var regex = new Regex(@"^(?<hours>\d{1,2})\s*h\s*(?<minutes>\d{1,2})\s*m$"); 
    var match = regex.Match(value); 
    if (match.Success) { 
    var hours = Int32.Parse(match.Groups["hours"].Value); 
    var minutes = Int32.Parse(match.Groups["minutes"].Value); 
    if (hours < 24 && minutes < 60) 
     return hours + "." + minutes; 
    } 
    return null; 
} 

您可以调整正则表达式,以满足您的需求。这一个接受字符串如10 h 53 m10h53m

+0

'\ d {1,2}'真的可以排除不切实际的数字 – abatishchev 2011-05-23 15:27:01

相关问题