【问题标题】:Extract GUID from line in C#从 C# 中的行中提取 GUID
【发布时间】:2017-05-30 22:49:21
【问题描述】:

我尝试使用 IndexOf 从行中检索 GUID 来简化一些遗留代码。我可以进一步简化下面的代码以摆脱使用 guids.Any 和 guids.First 吗?

// 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;
        }
    }
}

【问题讨论】:

  • 你为什么不直接使用 guid.tryparse
  • Guid.TryParse() 比尝试使用自己的正则表达式解析 GUID 好得多
  • 是的,只需使用 xdoc 获取值并解析 guid
  • CTRL+A, CTRL+C, Edit\Paste Special\Paste XML as Classes, Deserialize Xml, 以文明的方式做你的事。或者,如果你不够文明,你也可以使用 XPath。

标签: c#


【解决方案1】:

是的,你可以。因为你只返回正则表达式的第一个匹配,你可以使用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;
}

【讨论】:

    【解决方案2】:

    使用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();
    

    【讨论】:

      【解决方案3】:

      只是为了提供使用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。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-28
        • 2021-01-18
        • 2016-09-09
        • 1970-01-01
        • 1970-01-01
        • 2016-01-26
        • 1970-01-01
        • 2014-10-27
        相关资源
        最近更新 更多