C#正则表达式用于Guid

169
我需要解析一个字符串,并在每个 Guid 值周围添加单引号。我想使用正则表达式来完成这个任务,但我并不是一个正则表达式专家。
有没有一个好的正则表达式可以用来识别 Guid?
我的第二个问题是,一旦我找到一个有效的正则表达式,我假设我会使用 Regex.Replace(String, String, MatchEvaluator),但我不太确定语法。也许像这样:
return Regex.Replace(stringToFindMatch, GuidRegex, match =>
{
    return string.Format("'{0}'", match.Groups[0].ToString());
});

我正在尝试解析的字符串可能如下所示:

"SELECT passwordco0_.PASSWORD_CONFIG_ID as PASSWORD1_46_0_, FROM PASSWORD_CONFIG passwordco0_ WHERE passwordco0_.PASSWORD_CONFIG_ID=baf04077-a3c0-454b-ac6f-9fec00b8e170; @p0 = baf04077-a3c0-454b-ac6f-9fec00b8e170 [Type: Guid (0)]"


7
那是SQL语句,你应该使用SQL参数。 - jrummell
2
为什么要使用正则表达式,当有GUID.IsGuid可用呢? - Micah Armantrout
@jrummell 这是来自分析器的输出。我正在尝试转换输出,以便我可以复制粘贴并在SQL Management Studio中运行它。这仅用于记录目的。它仍将作为参数化的SQL运行。 - Cole W
@MicahArmantrout - 当在NUnit或其他接受正则表达式作为参数的例程中进行字符串比较时,正则表达式可能会很有帮助。例如:StringAssert.IsMatch("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}", MyInstance.GUID); - ftexperts
1
猜测是错误的,我退出了 http://msdn.microsoft.com/en-us/library/system.guid.tryparse(v=vs.110).aspx - Micah Armantrout
显示剩余6条评论
7个回答

237

这个很简单,不需要像你说的那样使用委托。

resultString = Regex.Replace(subjectString, 
     @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$", 
     "'$0'");

以下这些样式都是GUID的等效和可接受的格式,可以匹配该正则表达式。

ca761232ed4211cebacd00aa0057b223
CA761232-ED42-11CE-BACD-00AA0057B223
{CA761232-ED42-11CE-BACD-00AA0057B223}
(CA761232-ED42-11CE-BACD-00AA0057B223)

更新1

@NonStatic在评论中指出,上述正则表达式将匹配错误的结束定界符导致误报。

可以通过正则条件避免这种情况,正则条件得到广泛支持。

条件语句被JGsoft引擎、Perl、PCRE、Python和.NET框架支持。Ruby从2.0版本开始支持条件语句。像Delphi、PHP和基于PCRE的正则表达式功能的R等语言也支持条件语句。(来源http://www.regular-expressions.info/conditional.html

接下来的正则表达式将匹配:

{123}
(123)
123

不会匹配

{123)
(123}
{123
(123
123}
123)

正则表达式:

^({)?(\()?\d+(?(1)})(?(2)\))$

解决方案简化为仅匹配数字,以更清晰地展示必要的内容(如果需要)。


7
这不考虑小写字符,但仍属有效情况。使用^[{|(]?[0-9a-fA-F]{8}[-]?([0-9a-fA-F]{4}[-]?){3}[0-9a-fA-F]{12}[)|}]?$或使用/i标志。 - Michael Brown
@NonStatic 是的,没错。如果需要的话,你可以使用我的更新1来防止这种误报。 - buckley
@AntonioManello {(123)}不匹配,因为它不是正确的GUID。更新是针对起始分隔符与结束分隔符不同的情况。 - buckley
3
正则表达式也允许少于4个减号。对于那些关心此事的人来说,FYI。对于那些不关心的人,这是一个更简单的正则表达式,它允许更多错误匹配: [0-9a-fA-F\-]{32,36} - usr
1
无法在 https://support.office.com/en-us/article/poisson-function-d81f7294-9d7c-4f75-bc23-80aa8624173a 上运行。 - zmechanic
显示剩余9条评论

71

最基本的正则表达式如下:

(^([0-9A-Fa-f]{8}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{4}[-]?[0-9A-Fa-f]{12})$) 

或者你可以在这里粘贴它

希望这能节省你一些时间。


不如建议答案那么详细,但是感谢提供 regex101.com 的链接。 - Jim Billig
16
将重复的部分删除:[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}。将破折号可选化:[0-9A-Fa-f]{8}-?([0-9A-Fa-f]{4}-?){3}[0-9A-Fa-f]{12} - Louis Somers
@LouisSomers 可以在开括号后添加 ?: 来使该组不捕获。 - OfirD

36

用于在给定文本中查找和替换任何 GUID 样式字符串的 C# .Net 正则表达式:

使用以下正则表达式:

[({]?[a-fA-F0-9]{8}[-]?([a-fA-F0-9]{4}[-]?){3}[a-fA-F0-9]{12}[})]?

示例 C# 代码:

var result = Regex.Replace(
      source, 
      @"[({]?[a-fA-F0-9]{8}[-]?([a-fA-F0-9]{4}[-]?){3}[a-fA-F0-9]{12}[})]?", 
      @"${ __UUID}", 
      RegexOptions.IgnoreCase
);

肯定有效!它匹配和替换以下风格,这些风格都是GUID的等效和可接受格式。

"aa761232bd4211cfaacd00aa0057b243" 
"AA761232-BD42-11CF-AACD-00AA0057B243" 
"{AA761232-BD42-11CF-AACD-00AA0057B243}" 
"(AA761232-BD42-11CF-AACD-00AA0057B243)" 

6
接受的答案对我没用,但这个可以! - Merin Nakarmi
这里有一个问题。Guid 只包含十六进制数字。因此,a-z 和 A-Z 中的字母不被接受,只有 a-f 和 A-F 被接受。否则,它会将任何具有 32 个字符的文本都认为是有效的 Guid。 - Merin Nakarmi
同上 - 接受的答案对我没用,但这个可以! - Greg Trevellick
你设置了 RegexOptions.IgnoreCase - 因此 [a-f0-9] 就足够了。 - kara
是的,同意,忽略掉它,因为它不会造成影响。IgnoreCase 是最初答案中加入的,然后我在正则表达式中添加了 [a-f0-9],如果我没记错的话。 - GDroid

10
你可以使用http://regexhero.net/tester/来轻松自动生成C#代码。

它是免费的。

这是我是如何做的:

enter image description here

然后该网站会自动生成.NET代码:

string strRegex = @"\b[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}\b";
Regex myRegex = new Regex(strRegex, RegexOptions.None);
string strTargetString = @"     {CD73FAD2-E226-4715-B6FA-14EDF0764162}.Debug|x64.ActiveCfg =         Debug|x64";
string strReplace = @"""$0""";

return myRegex.Replace(strTargetString, strReplace);

2
我还会包括小写字符 a-f,以确保支持小写 GUID。 - Sean Feldman

9
在.NET Framework 4中,有对System.Guid结构的增强,其中包括新的TryParse和TryParseExact方法来解析GUID。以下是示例。
    //Generate New GUID
    Guid objGuid = Guid.NewGuid();
    //Take invalid guid format
    string strGUID = "aaa-a-a-a-a";

    Guid newGuid;

    if (Guid.TryParse(objGuid.ToString(), out newGuid) == true)
    {
        Response.Write(string.Format("<br/>{0} is Valid GUID.", objGuid.ToString()));
    }
    else
    {
        Response.Write(string.Format("<br/>{0} is InValid GUID.", objGuid.ToString()));
    }


    Guid newTmpGuid;

    if (Guid.TryParse(strGUID, out newTmpGuid) == true)
    {
        Response.Write(string.Format("<br/>{0} is Valid GUID.", strGUID));
    }
    else
    {
        Response.Write(string.Format("<br/>{0} is InValid GUID.", strGUID));
    }

在这个例子中,我们创建了一个新的guid对象,并且还使用了一个包含无效guid的字符串变量。之后,我们使用TryParse方法来验证两个变量是否具有有效的guid格式。通过运行示例,您可以看到字符串变量没有有效的guid格式,并显示“无效的guid”消息。如果字符串变量具有有效的guid,则TryParse方法将返回true。

7
这个问题是在询问如何从一个较长的字符串中找到/提取一个GUID,而不是验证GUID。建议您删除这个答案。 - iCollect.it Ltd
15
可能这是一个“好”的回答,但它并不是针对这个问题的答案。如果您在任何地方都随意发布任何答案,那么这有点违背了StackOverflow的目的 :) - iCollect.it Ltd
8
对于像我这样搜索“regex for guid”的人来说,这个回答确实是最有用的——我不是__真的__需要一个正则表达式,我需要匹配GUID,并且这个页面是目前在谷歌上搜索“regex to detect guid”得到的第一个结果。 - Dan Field
3
支持 @Dan Field 的观点。我来这里寻找正则表达式的 GUID,发现这个答案正是我需要的。StackOverflow 的目的因此得到了实现。 - JLScott
这不是相关的答案,但当然很有帮助。我投了一票。 :) - Merin Nakarmi

7
我使用了一个更简单的正则表达式模式。
^[0-9A-Fa-f\-]{36}$

7
这将匹配的不仅仅是GUID。 - Satadru Biswas
它只会匹配仅包含Guid且没有其他内容的行。 - AFract

6
要简单地匹配带有连字符的GUID,像这样:
63F0DA57-5AA2-4271-B9DE-6FD68008EA98
aa76ae52-14f2-5774-A645-9d002a72dec1

我使用以下方法:

[a-fA-F\d]{8}-[a-fA-F\d]{4}-[a-fA-F\d]{4}-[a-fA-F\d]{4}-[a-fA-F\d]{12}

这是所有结果中最干净的一个。 - enko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接