【问题标题】:Match a string against an easy pattern将字符串与简单模式匹配
【发布时间】:2014-07-01 17:43:12
【问题描述】:

我正在尝试对我正在创建的程序进行验证,以便我需要让用户输入的模式不是硬编码的。字母或数字模式总是有可能发生变化,但当它发生变化时,我需要每个人都保持一致。另外,我希望经理能够在不依赖我的情况下控制进入的内容。是否可以使用正则表达式或其他字符串工具将输入与存储在数据库中的列表进行比较。我希望它很简单,因此存储在数据库中的模式看起来像 X###### 或 X######-X####### 等等。

【问题讨论】:

  • 您可能可以使用掩码(某种正则表达式)而不是真正的正则表达式:请参阅msdn.microsoft.com/en-us/library/… 这些可用于文本框以允许用户仅输入有效文本。
  • 是 WPF 还是 Win Form?请根据您的要求添加更多细节。 Rgds,

标签: c# regex string pattern-matching


【解决方案1】:

当然,只需将正则表达式规则存储在表格的字符串列中,然后将它们加载到应用程序中的IEnumerable<Regex> 中。然后,只要这些规则中的任何一个匹配,则匹配。请注意,相互冲突的规则可能会导致贪婪竞赛(第一个被检查的获胜者),因此您必须小心。另请注意,除了我的示例之外,您还可以执行许多优化,这些优化设计很简单。

List<string> regexStrings = db.GetRegexStrings();
var result = new List<Regex>(regexStrings.Count);
foreach (var regexString in regexStrings)
{
    result.Add(new Regex(regexString);
}

...

// The check
bool matched = result.Any(i => i.IsMatch(testInput));

【讨论】:

  • 这个例子确实有效,但我如何让它更动态地工作。如果输入是 X### 并且数据库具有 X###,则返回 true。我想要的是 X### 对 X123 为真,但对 X1234 为假。这种比较。
  • 另外,我希望数据库实际保存“X###”。我知道在 excel 中你可以创建这样的自定义字段
  • 你会使用正则表达式约束......有一些方法可以限制匹配输入。你需要做一些谷歌搜索来了解限制正则表达式输入的方法。
【解决方案2】:

您可以将模式按原样存储在数据库中,然后将它们转换为正则表达式。

我不知道您的格式中具体需要哪些字符,但假设您只想将一个数字替换为 # 并将其余部分保持原样,这里有一些代码:

public static Regex ConvertToRegex(string pattern)
{
    var sb = new StringBuilder();

    sb.Append("^");

    foreach (var c in pattern)
    {
        switch (c)
        {
            case '#':
                sb.Append(@"\d");
                break;

            default:
                sb.Append(Regex.Escape(c.ToString()));
                break;
        }
    }

    sb.Append("$");

    return new Regex(sb.ToString());
}

如果需要,您也可以使用 RegexOptions.IgnoreCase 之类的选项。

注意:出于某种原因,Regex.Escape 转义了 # 字符,即使它并不特殊......所以我只是采用逐个字符的方法。

【讨论】:

    【解决方案3】:
            private bool TestMethod()
    {
        const string textPattern = "X###";
        string text = textBox1.Text;
        bool match = true;
    
        if (text.Length == textPattern.Length)
        {
            char[] chrStr = text.ToCharArray();
            char[] chrPattern = textPattern.ToCharArray();
            int length = text.Length;
    
            for (int i = 0; i < length; i++)
            {
                if (chrPattern[i] != '#')
                {
                    if (chrPattern[i] != chrStr[i])
                    {
                        return false;
                    }
                }
            }
        }
        else
        {
            return false;
        }
        return match;
    }
    

    这正在做我现在需要做的一切。不过,感谢所有提示。将来我将不得不更多地研究正则表达式。

    【讨论】:

      【解决方案4】:

      使用MaskedTextProvider,您可以执行以下操作:

      using System.Globalization;
      using System.ComponentModel;
      
      string pattern = "X&&&&&&-X&&&&&&&";
      string text = "Xabcdef-Xasdfghi";
      
      var culture = CultureInfo.GetCultureInfo("sv-SE");
      var matcher = new MaskedTextProvider(pattern, culture);
      int position;
      MaskedTextResultHint hint;
      if (!matcher.Set(text, out position, out hint))
      {
          Console.WriteLine("Error at {0}: {1}", position, hint);
      }
      else if (!matcher.MaskCompleted)
      {
          Console.WriteLine("Not enough characters");
      }
      else if (matcher.ToString() != text)
      {
          Console.WriteLine("Missing literals");
      }
      else
      {
          Console.WriteLine("OK");
      }
      

      格式说明见:http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多