簡體   English   中英

比較並驗證兩個字符串

[英]Compare and validate two strings

// 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個字母是可以的,但是有效,但對於X和N來說,超過4個字母是無效的,可以更改/ or # or @ ,可以是/ or # or @任何東西。 如果我將使用正則表達式,它將檢查直到固定長度

此正則表達式似乎按預期工作

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

並用此代碼更改准備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);

但是,這需要進行更廣泛的測試……

如果您希望它是動態構建的,那么我將完全避免使用正則表達式。 構建一些對象來為您完成工作。

首先是一個非常簡單的類,僅用於通過任意匹配檢查來驗證單個字符:

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超出了簡單的“ 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:錯誤

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM