简体   繁体   English

将字符串与简单模式匹配

[英]Match a string against an easy pattern

I am trying to future proof a program I am creating so that the pattern I need to have users put in is not hard coded. 我正在尝试将来对我正在创建的程序进行证明,以使需要用户输入的模式不会被硬编码。 There is always a chance that the letter or number patter can change, but when it does I need everyone to remain consistent. 字母或数字的样式总是有可能改变的,但是当它改变时,我需要每个人保持一致。 Plus I want the managers to be to control what goes in without relying on me. 另外,我希望经理们能够控制一切而不必依靠我。 Is it possible to use regex or another string tool to compare input against a list stored in a database. 是否可以使用正则表达式或其他字符串工具将输入与数据库中存储的列表进行比较。 I want it to be easy so the patterns stored in the database would look like X###### or X######-X####### and so on. 我希望它很容易,以便存储在数据库中的模式看起来像X ######或X ######-X #######等等。

Sure, just store the regular expression rules in a string column in a table and then load them into an IEnumerable<Regex> in your app. 当然,只需将正则表达式规则存储在表的字符串列中,然后将其加载到应用程序的IEnumerable<Regex>中即可。 Then, a match is simply if ANY of those rules match. 然后,只要这些规则中的任何一个匹配,就匹配。 Beware that conflicting rules could be prone to greedy race (first one to be checked wins) so you'd have to be careful there. 当心规则冲突可能会导致贪婪竞赛(第一个被检查获胜),因此您必须在那儿小心。 Also be aware that there are many optimizations that you could perform beyond my example, which is designed to be simple. 还请注意,除了我的示例之外,您还可以执行许多优化,这些优化旨在简化。

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));

Using MaskedTextProvider , you could do do something like this: 使用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");
}

For a description of the format, see: http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask 有关格式的说明,请参见: http : //msdn.microsoft.com/zh-cn/library/system.windows.forms.maskedtextbox.mask

You could store your patterns as-is in your database, and then translate them to regexes. 您可以将模式原样存储在数据库中,然后将其转换为正则表达式。

I don't know specifically what characters you'd need in your format, but let's suppose you just want to substitute a number to # and leave the rest as-is, here's some code for that: 我不特别知道您需要使用哪种格式的字符,但让我们假设您只想将数字替换为# ,而其余​​部分保持原样,下面是一些代码:

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());
}

You can also use options like RegexOptions.IgnoreCase if that's what you need. 如果需要,还可以使用RegexOptions.IgnoreCase选项。

NB: For some reason, Regex.Escape escapes the # character, even though it's not special... So I just went for the character-by-character approach. 注意:由于某种原因, Regex.Escape转义#字符,即使它不是特殊的……所以我只是采用逐个字符的方法。

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

This is doing everything I need it to do now. 这正在做我现在需要做的所有事情。 Thanks for all the tips though. 感谢所有提示。 I will have to look into the regex more in the future. 将来我将不得不更多地研究正则表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM