// 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 @
任何东西。如果我将使用正则表达式,那么它将检查直到固定长度
答案 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(小写)现在将正则表达式模式应用于输入字符串,您只能找到第二个和第四个字符串的匹配项。
查看评论我试图构建一个简单的模式构建器。
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.IsLetter
和Char.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:错误