我是c#的初学者,我正在进行文字练习。我制作了一种方法来过滤车辆的车牌号码。它应该由3个字母和3个整数组成(AAA:152)。我的方法将错误的板号发送到文件,但它也将错误的号码添加到一个好的列表中。
private static string[] InvalidPlates(string[] csvLines, int fieldToCorrect)
{
var toReturn = new List<string>();
var toSend = new List<string>();
int wrongCount = 0;
for (int i = 0; i < csvLines.Length; i++)
{
string[] stringFields = csvLines[i].Split(csvSeparator[0]);
string[] values = stringFields[fieldToCorrect].Split(':');
if(Regex.IsMatch(values[0], @"^[a-zA-Z]+$") && Regex.IsMatch(values[1], "^[0-9]+$"))
{
toReturn.Add(string.Join(csvSeparator, stringFields));
}
else
{
toSend.Add(string.Join(csvSeparator, stringFields));
wrongCount++;
}
}
WriteLinesToFile(OutputFile, toSend.ToArray(), wrongCount);
return toReturn.ToArray();
}
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
您需要使用量词约束可能的长度:
^[a-zA-Z]{3}\:\d{3}$
字面意思如下,按严格的顺序:
字符串从正好3个小写或大写英文字母开始,以分号(
:
)继续,并以正好三位数结尾
请记住,\
应该在C#中转义。
此外,当您可以使用非拆分stringFields
时,无需将csvLines[i]
加入字符串:
if (Regex.IsMatch(stringFields, @"^[a-zA-Z]{3}\\:\\d{3}$"))
toReturn.Add(csvLines[i]);
}
else
{
toSend.Add(csvLines[i]);
wrongCount++;
}
另一个重要的事情是你的代码在OOP方面是不正确的。显而易见的是,名为InvalidPlates
的方法会将某些内容保存到文件中。一段时间后或其他开发人员可能会让您感到困惑。应该没有“隐藏”功能,所有方法实际上应该只做一件事。
以下是使用LINQ执行此操作的方法:
private static bool IsACorrectPlate(string p) => Regex.IsMatch(p, @"^[a-zA-Z]{3}\:\d{3}$");
private static void SortPlatesOut(string[] csvLines, int column, out string[] correct, out string[] incorrect)
{
var isCorrect = csvLines
.GroupBy(l => IsACorrectPlate(l.Split(';')[column]))
.ToDictionary(g => g.Key, g => g.ToArray());
correct = isCorrect[true];
incorrect = isCorrect[false];
}
// Usage:
string[] incorrect, correct;
SortPlatesOut(csvLines, 1, out correct, out incorrect);
File.WriteAllLines("", incorrect);
// do whatever you need with correct
现在,SortPlatesOut
方法具有可预期的行为,没有副作用。代码也缩短了两倍。与此同时,它对我来说更具可读性。如果它看起来不可读,你可以解压缩LINQ并将其他东西分开。