2013-04-05 4 views
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; 
} 

Я хочу, чтобы проверить strToBeValidated с strForMatching.

Это означает, что:

  • 333TEST не является действительным
  • ABCD2345-1234-AB действует
  • PPP12AA-9876 действует
  • PPPPP12AX-1234-AB не является действительным.

Какое бы значение оно ни было, должно соответствовать strForMatching. Мне также необходимо проверить разделитель.

Я не могу использовать регулярное выражение, потому что у меня есть AAAAXXX-NNNN-AA, в моем случае от 1 до 4 алфавита в порядке, но более 4 алфавитов недействительны, как для X и N, а отдельно может быть изменено, это может быть / or # or @ что-нибудь. Если я буду использовать регулярные выражения, то он будет проверять до длины починки

+7

попробуйте использовать регулярные выражения: http://en.wikipedia.org/wiki/Regular_expression – pascalhein

+0

Я использую приложение Windows – Rocky

+0

'Я использую приложение Windows 'Итак? просто используйте ['System.Text.RegularExpressions'] (http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx) в вашем приложении Windows. Они не являются взаимоисключающими. – Nolonar

ответ

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 (нижний регистр)
  • Второй набор из четырех символов должен быть как и раньше но может также содержит цифры 0-9
  • Символ минус будет следовать
  • Третий набор из четырех символов просто числа
  • Символ минус будет следовать
  • Четвертый набор из 2 символов являются только alphabetich символов

Теперь, применяя шаблон 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); 

Однако это должны быть проверены более тщательно ......

+0

вы также можете использовать 'if (r .IsMatch (s)) ' – pascalhein

+0

, если в следующий раз я получу еще одну строку в strForMatching, например, AAAA-XXXX или XXX-NNNN-AA или NNN-AA-XXX. Я не хочу держать что-либо жестко закодированным. В моем сценарии у меня есть значение выбора пользователя combobox из combobox, значение которого равно strForMatching. – Rocky

+1

Если характер матча является динамическим, как следует из вашего комментария, вам нужно динамически строить шаблон. Вы можете перевести свои A, N и X в соответствующие шаблоны Regex (A-Za-z) и т. Д., Затем подсчитайте появление A, N и X, чтобы определить количество допустимых символов {x}. Как вы можете видеть, exaustive работа - непростая задача. – Steve

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, которые немного отличаются от простых «A-Z» и «0-9», но этого должно быть достаточно, чтобы продемонстрировать, как это работает. Не стесняйтесь заменять эти конкретные проверки регулярным выражением или другой проверкой, если хотите.

Кроме того, ваш пример правил/выходов казался выключенным (например, я ожидал бы «PPP12AA-9876» до не матч против «AAAAXXXXX-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: True
PPP12AA-9876: False

+0

последнее значение показывает False, но в моем случае это должно быть правдой, stringToValidate может быть меньше или равно strForMatching, но не должно превышать strForMatching – Rocky

+0

@Rocky Но у него также есть только 3 символа "P" начало. Если бы он соответствовал, даже если бы он был короче, не должен ли он иметь 4 "P"?Или это не имеет значения, если он обрезается с самого начала или конца? В любом случае, вам должно быть легко окунуться в метод 'ValidateString'. –

+0

У меня есть AAAAXXX-NNNN-AA, в моем случае от 1 до 4 алфавита в порядке, но более 4 алфавитов недействительны, как для X и N, а отдельное может быть изменено, это может быть/или # или @ ничего – Rocky

Смежные вопросы