比较并验证两个字符串

时间:2013-04-05 10:09:20

标签: c# string validation

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

我想使用strToBeValidated验证strForMatching

这意味着:

  • 333TEST无效
  • ABCD2345-1234-AB有效
  • PPP12AA-9876有效
  • PPPPP12AX-1234-AB无效。

有什么价值应与strForMatching相匹配。我还需要验证分隔符。

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

2 个答案:

答案 0 :(得分: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}应在A-Z范围内(上限) case)或a-z(小写)
  • 第二组四个角色应该像以前一样,但也可以 包含数字0-9
  • 后面会出现一个减号
  • 第三组四个字符只是数字
  • 后面会出现一个减号
  • 第四组2个字符只是字母字符

现在将正则表达式模式应用于输入字符串,您只能找到第二个和第四个字符串的匹配项。

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

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

使用以下代码更改准备Regex模式的代码:

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

然而,这需要进行更广泛的测试......

答案 1 :(得分: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.IsLetterChar.IsDigit的规则有点超出简单的“A-Z”和“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:错误