使用Regex

时间:2019-01-15 21:07:02

标签: c# regex guid

GUID可能出现在带有或不带有单引号的语句中,例如

string inputString = @"ObjectID='{A591C480-2979-48ED-9796-5C3149472E7A}' and ObjectID={90f0fb85-0f80-4466-9b8c-2025949e2079}";

我的要求是:

  

如果GUID用单引号引起来,请跳过它。
  如果它没有用单引号引起来,则用单引号引起来。

我希望输出像

inputString = @"ObjectID='{A591C480-2979-48ED-9796-5C3149472E7A}' and ObjectID='{90f0fb85-0f80-4466-9b8c-2025949e2079}'"

inputString = @"ObjectID='{A591C480-2979-48ED-9796-5C3149472E7A}' and ObjectID={'90f0fb85-0f80-4466-9b8c-2025949e2079'}"

在单引号内查找GUID的正则表达式是

var quotedGuidMatches = Regex.Matches(inputString, @"'[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?([a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?'");

找到GUID的正则表达式是

var guidMatches = Regex.Matches(inputString, @"\b[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?([a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?\b");

用单引号括住GUID的正则表达式是

inputString = Regex.Replace(inputString, @"\b[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?([a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?\b", "'$0'", RegexOptions.IgnoreCase);

不幸的是,这一行在单引号内找到了所有GUID,而没有单引号。 replace方法将最终围绕已经具有单引号和多个单引号的guid。
您能否帮助我找到不只包含在单引号内的GUID。然后用单引号引起来。

3 个答案:

答案 0 :(得分:1)

您可以在单引号内匹配一个GUID并捕获它,以便能够在匹配评估器中测试该组是否匹配,并在所有其他用单引号括起来的上下文中匹配一个GUID:

var inputString = @"ObjectID='{A591C480-2979-48ED-9796-5C3149472E7A}' and ObjectID={90f0fb85-0f80-4466-9b8c-2025949e2079}";
var guid = @"[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?(?:[a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?";
inputString = Regex.Replace(inputString, $@"('{guid}')|{guid}", x =>
    x.Groups[1].Success ? x.Value : $"'{x.Value}'");
Console.WriteLine(inputString);
// => ObjectID='{A591C480-2979-48ED-9796-5C3149472E7A}' and ObjectID='{90f0fb85-0f80-4466-9b8c-2025949e2079}'

请参见C# demo

请注意,我将原始模式([a-zA-Z0-9]{4}\s?[-]?\s?)中的(?:[a-zA-Z0-9]{4}\s?[-]?\s?)捕获组设为非捕获。

$@"('{guid}')|{guid}"字符串文字会创建像

这样的正则表达式
('[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?(?:[a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?')|[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?(?:[a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?

第一个备选方案将单引号内的GUID匹配并捕获到组1中,第二个备选方案在其他上下文中匹配GUID。如果x => x.Groups[1].Success ? x.Value : $"'{x.Value}'"行还没有用单引号引起来,则仅用'来包装匹配项。

答案 1 :(得分:0)

如果不需要正则表达式,为什么不使用简单的方法呢?

void Main()
{
    string ObjectID="'{A591C480-2979-48ED-9796-5C3149472E7A}'";

    if (!(ObjectID.StartsWith("'") && ObjectID.EndsWith("'")))
    {
        ObjectID = $"'{ObjectID.Trim('\'')}'";
    }

    Console.WriteLine(ObjectID);
}

我将调用添加到Trim中,以防字符串的开头或结尾仅带有单撇号。

答案 2 :(得分:0)

我想出了这个解决方案。这个想法是从带有引号的Guid中删除引号。然后将引号添加到所有(裸)向导。如果还有其他解决方案可以找到Guid 的单引号,并使用正则表达式将其括在单引号中,则我可以接受为答案。

using System;
using System.Text.RegularExpressions;

namespace RegexTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputString = @"ObjectID = '{A591C480-2979-48ED-9796-5C3149472E7A}' and ObjectID = { 90f0fb85 - 0f80 - 4466 - 9b8c - 2025949e2079 }";
            Console.WriteLine("Before: ");
            Console.WriteLine(inputString);

            var quotedGuidMatches = Regex.Matches(inputString, @"'[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?([a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?'");

            var guidMatches = Regex.Matches(inputString, @"\b[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?([a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?\b");

            //First eliminate single quotes from guoted guids
            foreach(var quotedGuid in quotedGuidMatches)
            {
                inputString = inputString.Replace(quotedGuid.ToString(), quotedGuid.ToString().Trim('\''));
            }            

            //After single quotes have been eliminated from guids, surround all naked guids with single quotes
            inputString = Regex.Replace(inputString, @"\b[({]?\s?[a-zA-Z0-9]{8}\s?[-]?\s?([a-zA-Z0-9]{4}\s?[-]?\s?){3}\s?[a-zA-Z0-9]{12}\s?[})]?\b", "'$0'", RegexOptions.IgnoreCase);

            Console.WriteLine("\nAfter: ");
            Console.WriteLine(inputString);

            Console.ReadLine();
        }
    }
}

enter image description here