使用RegEx比较两个值

时间:2010-12-09 15:43:37

标签: c# .net regex .net-3.5 c#-3.0

如果我有两个值,例如/ ABC001和ABC100或A0B0C1和A1B0C0,我是否可以使用RegEx来确保这两个值具有相同的模式?

5 个答案:

答案 0 :(得分:2)

如果您事先不知道该模式,但只会遇到两组字符(字母和数字),那么您可以执行以下操作:

编写一些解析第一个模式的C#,查看每个char并确定它是alpha还是digit,然后根据该模式生成一个正则表达式。

您可能会发现编写代码以生成正则表达式没有意义,因为检查第二个字符串与第一个字符串一样简单。

或者,没有正则表达式:

首先检查字符串的长度是否相同。 然后同时遍历两个字符串,char by char。如果字符串1中的char [x]是alpha,而字符串2中的char [x]是相同的,则表示模式匹配。

试试这个,如果一个字符串潜入某些符号,它应该应对。 编辑比较字符值 ... 并使用Char.IsLetter和Char.IsDigit

private bool matchPattern(string string1, string string2)
{
    bool result = (string1.Length == string2.Length);
    char[] chars1 = string1.ToCharArray();
    char[] chars2 = string2.ToCharArray();

    for (int i = 0; i < string1.Length; i++)
    {
        if (Char.IsLetter(chars1[i]) != Char.IsLetter(chars2[i]))
        {
            result = false;
        }
        if (Char.IsLetter(chars1[i]) && (chars1[i] != chars2[i]))
        {   
            //Characters must be identical
            result = false;
        }
        if (Char.IsDigit(chars1[i]) != Char.IsDigit(chars2[i]))
            result = false;
    }
    return result;
}

答案 1 :(得分:2)

嗯,这是我的镜头。这不使用正则表达式,并假设s1s2仅包含数字或数字:

public static bool SamePattern(string s1, string s2)
{
   if (s1.Length == s2.Length)
   {
      char[] chars1 = s1.ToCharArray();
      char[] chars2 = s2.ToCharArray();

      for (int i = 0; i < chars1.Length; i++)
      {
         if (!Char.IsDigit(chars1[i]) && chars1[i] != chars2[i])
         {
            return false;
         }
         else if (Char.IsDigit(chars1[i]) != Char.IsDigit(chars2[i]))
         {
            return false;
         }
      }

      return true;
   }
   else
   {
      return false;
   }
}

该算法的描述如下:

  1. 如果字符串长度不同,请返回false
  2. 否则,检查两个字符串中相同位置的字符:
    1. 如果它们都是数字或两个数字,请继续下一次迭代。
    2. 如果它们不是数字但不相同,请返回false
    3. 如果一个是数字而一个是数字,请返回false
  3. 如果两个字符串中的所有字符都已成功检查,请返回true

答案 2 :(得分:1)

考虑使用Char.GetUnicodeCategory
您可以为此任务编写辅助类:

public class Mask
{
    public Mask(string originalString)
    {
        OriginalString = originalString;
        CharCategories = originalString.Select(Char.GetUnicodeCategory).ToList();
    }

    public string OriginalString { get; private set; }
    public IEnumerable<UnicodeCategory> CharCategories { get; private set; }

    public bool HasSameCharCategories(Mask other)
    {
        //null checks
        return CharCategories.SequenceEqual(other.CharCategories);
    }
}

用作

Mask mask1 = new Mask("ab12c3");
Mask mask2 = new Mask("ds124d");
MessageBox.Show(mask1.HasSameCharCategories(mask2).ToString());

答案 3 :(得分:0)

我不知道C#语法,但这里是伪代码:

  • 将字符串拆分为''
  • 对2个阵列进行排序
  • 使用''
  • 加入每个数组
  • 比较2个字符串

答案 4 :(得分:0)

使用LINQ的通用解决方案可以非常容易地实现。这个想法是:

  1. 对两个字符串进行排序(重新排序字符)。
  2. 使用SequenceEquals将每个排序后的字符串作为字符序列进行比较。
  3. 此方案可实现简短,优雅且可配置的解决方案,例如:

    // We will be using this in SequenceEquals
    class MyComparer : IEqualityComparer<char>
    {
        public bool Equals(char x, char y)
        {
            return x.Equals(y);
        }
    
        public int GetHashCode(char obj)
        {
            return obj.GetHashCode();
        }
    }
    
    // and then:
    var s1 = "ABC0102";
    var s2 = "AC201B0";
    
    Func<char, double> orderFunction = char.GetNumericValue;
    var comparer = new MyComparer();
    var result = s1.OrderBy(orderFunction).SequenceEqual(s2.OrderBy(orderFunction), comparer);
    
    Console.WriteLine("result = " + result);
    

    正如您所看到的,它只有3行代码(不包括比较器类)。它也非常容易配置。

    • 现有代码会检查s1s2的排列。
    • 您想检查s1是否与s2具有相同数量和类型的字符,但不一定是相同字符(例如“ABC”等于“ABB”)?没问题,请将MyComparer.Equals更改为return char.GetUnicodeCategory(x).Equals(char.GetUnicodeCategory(y));
    • 通过更改orderFunctioncomparer的值,您可以配置众多其他比较选项。

    最后,由于我没有发现定义MyComparer类只是为了启用这个场景非常优雅,你也可以使用这个问题中描述的技术:

    Wrap a delegate in an IEqualityComparer

    将比较器定义为内联lambda。这将导致包含在2-3行代码中的可配置解决方案。