2017-05-30 45 views
1

我嘗試使用IndexOf來簡化一些遺留代碼以從行中檢索GUID。我可以進一步簡化下面的代碼來擺脫使用guids.Any和guids.First?從C#中提取GUID#

// Code using regular expression 
private static string RetrieveGUID2(string[] lines) 
{ 
    string guid = null; 
    foreach (var line in lines) 
    { 
     var guids = Regex.Matches(line, @"[{(]?[0-9A-F]{8}[-]?([0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?") 
      .Cast<Match>().Select(m => m.Value); 
     if (guids.Any()) 
     { 
      guid = guids.First(); 
      break; 
     } 
    } 
    return guid; 
} 

下面的樣本中給出的遺留代碼編譯:

using System; 
using System.Linq; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication2 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      var lines = new[] 
      { 
       "</ItemGroup>\n", 
       "<PropertyGroup\n", 
       "Label = \"Globals\">\n", 
       "<ProjectGuid>{A68615F1-E672-4B3F-B5E3-607D9C18D1AB}</ProjectGuid>\n", 
       "</PropertyGroup>\n" 
      }; 

      Console.WriteLine(RetrieveGUID(lines)); 
      Console.WriteLine(RetrieveGUID2(lines)); 
     } 

     // Legacy code 
     private static string RetrieveGUID(string[] lines) 
     { 
      string guid = null; 
      foreach (var line in lines) 
      { 
       var startIdx = line.IndexOf("<ProjectGuid>{", StringComparison.Ordinal); 
       if (startIdx < 0) continue; 
       var endIdx = line.IndexOf("</ProjectGuid>", StringComparison.Ordinal); 
       if (endIdx < 0) continue; 
       startIdx += "<ProjectGuid>".Length; 
       var guidLen = endIdx - startIdx; 
       guid = line.Substring(startIdx, guidLen); 
       break; 
      } 
      return guid; 
     } 

     // Code using regular expression 
     private static string RetrieveGUID2(string[] lines) 
     { 
      string guid = null; 
      foreach (var line in lines) 
      { 
       var guids = Regex.Matches(line, @"[{(]?[0-9A-F]{8}[-]?([0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?") 
        .Cast<Match>().Select(m => m.Value); 
       if (guids.Any()) 
       { 
        guid = guids.First(); 
        break; 
       } 
      } 
      return guid; 
     } 
    } 
} 
+4

你爲什麼不使用guid.tryparse –

+8

['Guid.TryParse()'](https://msdn.microsoft.com/en-us/library/system.guid.tryparse(v = vs。 110).aspx)會比嘗試使用自己的正則表達式來解析GUID好得多 – Liam

+0

是啊,只需使用xdoc獲取值並解析guid –

回答

2

是的,你可以。因爲您只返回正則表達式的第一個匹配項,您可以使用Regex.Match而不是Regex.Matches

private static string RetrieveGUID2(string[] lines) 
{ 
    foreach (var line in lines) 
    { 
     var match = Regex.Match(line, @"[{(]?[0-9A-F]{8}[-]?([0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?"); 
     if (match.Success) 
      return match.Value; 
    } 

    return null; 
} 
1

使用foreach環打破了在第一次迭代 - 這實際上是如何FirstFirstOrDefault實現

foreach(var nextGuid in guids) { guid = nextGuid; break; } 

進一步簡化它,您可以使用FirstOrDefault,如果沒有對象,將不會引發錯誤

return Regex 
    .Matches(line, @"[{(]?[0-9A-F]{8}[-]?([0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?") 
    .Cast<Match>() 
    .Select(m => m.Value) 
    .FirstOrDefault(); 
1

只是爲了提供使用Guid.TryParse()一種替代方案:

public static Guid? RetrieveGuid(IEnumerable<string> lines) 
{ 
    Guid? parseGuid(string text) => Guid.TryParse(text, out Guid guid) ? (Guid?) guid : null; 
    return lines.Select(parseGuid).FirstOrDefault(guid => guid != null); 
} 

或等價:

public static Guid? RetrieveGuid(IEnumerable<string> lines) 
{ 
    return lines.Select(line => Guid.TryParse(line, out Guid guid) ? (Guid?)guid : null) 
     .FirstOrDefault(guid => guid != null); 
} 

這將返回一個Guid?而不是字符串,並null結果意味着沒有有效Guid被解析。