1
// A = Alphabetic, X = Alphanumeric, N = Numeric character

string strForMatching = "AAAAXXXX-NNNN-AA";

string[] strToBeValidated = new string[]
{
    "333TEST",
    "TEST4444-1234-AB",
    "ABCD12AB-1234-99",
    "ABCD2345-1234-AB",
    "PPP12AA-9876"
};

通过for循环,我将字符串数组中的每个字符串传递给此方法

public bool ValidateString(string strForMatching, string strToBeValidated)
{
    bool isValid = false;

    // what to put here?

    return isValid;
}

我想strToBeValidatedstrForMatching.

这意味着:

  • 333TEST无效
  • ABCD2345-1234-AB已验证
  • PPP12AA-9876已验证
  • PPPPP12AX-1234-AB无效。

任何价值都应该与strForMatching. 我还需要验证分隔符。

我不能使用正则表达式,因为我有AAAAXXX-NNNN-AA,在我的情况下,1 到 4 个字母是可以的,但超过 4 个字母与 X 和 N 一样无效,并且可以单独更改它可以是/ or # or @任何东西。如果我将使用正则表达式,那么它将检查直到固定长度

4

2 回答 2

1

此正则表达式似乎按预期工作

string[] strTobeValidate = new string[] {"333TEST", "TEST4444-1234-AB", "ABCD12AB-1234-99", "ABCD2345-1234-AB", "PPP12AA-9876" };
Regex r = new Regex(@"[A-Za-z]{4}[A-Za-z0-9]{4}-[0-9]{4}-[A-Za-z]{2}");
foreach(string s in strTobeValidate)
{
    Match m = r.Match(s);
    if(m.Success == false)
        Console.WriteLine("No match for: " + s);
    else
        Console.WriteLine(m.ToString());

}

意义:

  • 第一组四个字符{4}应在 AZ(大写)或 az(小写)范围内
  • 第二组四个字符应该和以前一样,但也可以包含数字 0-9
  • 后面会出现一个减号
  • 第三组四个字符只是数字
  • 后面会出现一个减号
  • 第四组 2 个字符只是字母字符

现在将 Regex 模式应用于您的输入字符串,您会发现仅匹配第二个和第四个字符串。

查看评论,我尝试构建一个简单的模式构建器。

string BuildPattern(string h)
{
    StringBuilder sb = new StringBuilder();
    string curPattern = "";
    char curChar = ' ';
    int cnt = 0;
    foreach(Char c in h)
    {
        if(c != curChar && cnt != 0)
        {
            sb.Append(curPattern);
            sb.Append("{" + cnt.ToString() + "}");
            cnt = 0;
            curPattern = "";
        }
        curChar = c;
        switch(c)
        {
            case 'A':
                curPattern = "[A-Za-z]";
                cnt++;
                break;
            case 'X':
                curPattern = "[A-Za-z0-9]";
                cnt++;
                break;
            case 'N':
                curPattern = "[0-9]";
                cnt++;
                break;
            default:
                sb.Append(c);
                break;
        }
    }
    sb.Append(curPattern);
    sb.Append("{" + cnt.ToString() + "}");
    return sb.ToString();
}

并用这个更改准备正则表达式模式的代码:

string strForMatching = "AAAANNAA-NNNN-NN";
string pattern = BuildPattern(strForMatching);
// Fixed -> Regex r = new Regex(@"[A-Za-z]{4}[A-Za-z0-9]{4}-[0-9]{4}-[A-Za-z]{2}");
// Dynamic pattern 
Regex r = new Regex(pattern);

然而,这需要更广泛地测试......

于 2013-04-05T10:18:27.890 回答
0

如果您希望它是动态构建的,那么我将完全避免使用正则表达式。构建一些对象来为您完成工作。

首先是一个非常简单的类,用于通过任意匹配检查来验证单个字符:

public class Matcher
{
    public char Flag { get; private set; }
    private readonly Predicate<char> Checker;

    public Matcher(char flag, Predicate<char> checker)
    {
        this.Flag = flag;
        this.Checker = checker;
    }

    public bool DoesMatch(char character)
    {
        return Checker(character);
    }
}

然后是一些完成繁重工作的验证类:

public class StringValidator
{
    private Dictionary<char, Matcher> Matchers = new Dictionary<char, Matcher>();

    public StringValidator()
    {
        Matchers = new[]{
            new Matcher('A', c => Char.IsLetter(c)),
            new Matcher('N', c => Char.IsDigit(c)),
            new Matcher('X', c => Char.IsLetter(c) || Char.IsDigit(c)),
            new Matcher('-', c => c == '-')}
            .ToDictionary(m => m.Flag);
    }

    public bool ValidateString(string strForMatching, string strTobeValidated)
    {
        if (strForMatching.Length != strTobeValidated.Length)
            return false;

        for(int i = 0; i < strTobeValidated.Length; i++)
        {
            Matcher matcher = GetMatcher(strForMatching[i]);

            if (!matcher.DoesMatch(strTobeValidated[i]))
                return false;
        }

        return true;
    }

    private Matcher GetMatcher(char flag)
    {
        Matcher matcher;

        if(!Matchers.TryGetValue(flag, out matcher))
            throw new IndexOutOfRangeException(String.Format("No matcher for character '{0}'", flag));

        return matcher;
    }
}

现在,您如何选择创建匹配例程或组织它们,或者它们的标志取决于您。在这种情况下,StringValidator它的规则是“硬编码的”,但您可以更改它以通过构造函数将它们传递或通过公共方法进行更改。

此外,我使用的规则Char.IsLetter有点Char.IsDigit超出简单的“AZ”和“0-9”,但应该足以证明它是如何工作的。如果您愿意,请随意用正则表达式或其他检查替换这些特定检查。

此外,您的示例规则/输出似乎不正确(例如,我希望“PPP12AA-9876”与“AAAAXXXX-NNNN-AA”匹配)。这当前检查长度是否匹配,但您可以摆脱它。如果匹配模式比要验证的输入短(反之亦然),我对此并不肯定,所以我将根据您的确切要求将其留给您作为练习。

一些示例用法:

string[] stringsToValidate = new string[] { 
                                       "333TEST",
                                       "TEST4444-1234-AB",
                                       "ABCD12AB-1234-99",
                                       "ABCD2345-1234-AB",
                                       "PPP12AA-9876"
                                   };
string strForMatching = "AAAAXXXX-NNNN-AA";

var validator = new StringValidator();

foreach(var strToValidate in stringsToValidate)
{
    bool isValid = validator.ValidateString(strForMatching, strToValidate);
    Console.WriteLine(strToValidate + ": " + isValid);
}

输出:

333TEST:错误
TEST4444-1234-AB:正确
ABCD12AB-1234-99:错误
ABCD2345-1234-AB:正确
PPP12AA-9876:错误

于 2013-04-05T10:59:11.737 回答