【发布时间】:2014-02-09 13:35:24
【问题描述】:
我用 C# (WinForm) 编写了一个名为 address_parser.exe 的应用程序,针对运行 Windows XP、Vista、7 和 8 的 PC。使用 .NET Framework 3.5 版是最低设置...
应用程序读取并解析文本文件(仅限纯文本文件,因为我无法控制输入文件,所以很遗憾,XML 不是一个选项)。
这些文本文件包含一组数据,比如一个地址,分成多个不连续的行。
请看以下两个文本文件作为演示:
address_type_1.txt:
Elm Grove
47
PO5 1JF
Southsea
和
address_type_2.txt:
Southsea
Albert Road
147b
PO4 0JW
现在,目前我已经在我的代码中硬编码了输入文件中街道、门牌号、邮政编码和城市所在的信息。所以对于每个地址文件类型如果都创建了一套规则,哪一行包含了哪些信息。
此外,我还有一组正则表达式,用于检查每个信息(街道、门牌号、邮政编码、城市)的有效性。
由于这两组规则/检查(哪一行包含每个信息的信息/正则表达式模式)因不同的地址类型而异,我想将这些规则存储在一种配置文件中。因此,我不想硬编码,而是希望为每种地址类型都有一个配置文件,我的应用程序可以读取并配置自己如何解析特定的地址文件类型。
我想从你那里得到一些想法和灵感。请分享您的想法和最佳实践!
谢谢!
以下是我的一些想法,以及我目前使用的代码 sn-ps...
我目前的硬编码地址文件解析运行如下:
public static Address Parse(string fileName)
{
var a = new Address();
a.OriginalFile = fileName;
int i = 0;
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
{
using (var reader = new StreamReader(fs, Encoding.GetEncoding(65001)))
{
Regex rgxStreet = new Regex(@"^([\w\.,:\/\\\-öäüÖÄÜß_\s\(\)\[\]-[=;]]){0,128}$");
Regex rgxNumber = new Regex(@"^([\w\.,:\/\\\-öäüÖÄÜß_\s\(\)\[\]-[=;]]){0,20}$");
Regex rgxCity = new Regex(@"^([\w\.,:\/\\\-öäüÖÄÜß_\s\(\)\[\]-[=;]]){0,128}$");
Regex rgxZIP = new Regex(@"^([0-9]){5}$");
while (!reader.EndOfStream)
{
var line = reader.ReadLine().TrimEnd(';').Trim();
if (line != null)
{
if (i == 4 && rgxStreet.IsMatch(line))
{
a.Street = line;
}
else if (i == 7 && rgxNumber.IsMatch(line))
{
a.Number = line;
}
else if (i == 12 && (rgxZIP.IsMatch(line) || String.IsNullOrEmpty(line)))
{
a.Zip = line;
}
else if (i == 15 && rgxCity.IsMatch(line))
{
a.City = line;
}
}
i++;
}
}
}
return a;
}
如您所见,我还在这 4 个属性上使用了单独的正则表达式来检查我正在阅读的内容是否有效。
现在,我想修改这个硬编码信息(行 X 包含带有正则表达式 Z 的字段 Y),以便我可以支持读取和解析相同信息存储在不同文件中的文件顺序,或具有不同的有效值。
上面的示例针对包含德国地址(邮政编码为 5 位)的文件。
解析另一种类型的包含英国地址的文本文件可能如下所示:
line 1: city;
line 2: zip;
line 20: street;
line 159: number;
在此示例中,信息的顺序以及邮政编码所需的 reg ex 已更改(英国的邮政编码长度为 6 位,包含字母和数字)。
我想要一个配置文件之类的东西,它告诉我的应用程序如何解析特定类型的文件,而不是硬编码如何解析此类文件的信息。像这样的:
#config file for UK address files:
#line;field;regex;
1;city;@"^([\w\.,:\/\\\-öäüÖÄÜß_\s\(\)\[\]-[=;]]){0,128}$";
2;zip;@"^([A-Za-z0-9]){6}$";
20;street;@"^([\w\.,:\/\\\-öäüÖÄÜß_\s\(\)\[\]-[=;]]){0,128}$";
150;number;@"^([\w\.,:\/\\\-öäüÖÄÜß_\s\(\)\[\]-[=;]]){0,20}$";
我的问题是:这是个好主意,还是有更好的方法来实现这一点(告诉我的应用程序需要如何读取和解析特定文件以及解释和验证其内容) ?
谢谢!
【问题讨论】:
-
使用 XML。订单在那里并不重要。创建一个代表您的配置的类并使用 XML-Serializer 加载数据
-
输入格式是纯文本 - 因为我无法控制输入文件,不幸的是我不能使用 XML (:
标签: c# regex file-io configuration-files