使用正则表达式支持灵活的文本格式





5.00/5 (2投票s)
正则表达式使您的应用程序能够解析自定义格式的文本文件。
引言
我正在编写一个小型的数据库应用程序,允许用户将纯文本文件中的记录导入到Access数据库中。我遇到的一个问题是,不同的用户会有不同的格式:有些是制表符分隔的,有些是逗号分隔的;有些具有固定宽度的字段,而有些则没有。您可以使用switch语句来处理它们,但是当格式的数量增加时,代码的丑陋程度也会增加。更困难的是,通常在编码时您并不知道格式是什么。
因此,我需要支持自定义格式;它必须足够灵活,并且应用程序可以轻松理解。这看起来是一项艰巨的任务,直到我接触到正则表达式的概念。
Using the Code
它非常简单易用,因为它除了使用正则表达式的想法之外,几乎没有其他内容。演示项目包含在formats.xml中描述的两种格式,以及两个示例输入文件。您需要
- 将flex_format.cs添加到您的项目中。
- 在初始化期间加载存储在XML文件中的格式信息。
- 当用户打开
OpenFileDialog
时,将格式信息填充到文件过滤器中。 - 使用格式描述中指定的正则表达式解析文本文件。
- 要添加新格式,您可以手动编辑XML文件,也可以以编程方式使用XML序列化。这是演示项目中使用的XML文件的一部分。此格式允许用户使用不同的速度单位,如果没有正则表达式的帮助,这将更难实现。
//Read Formats Supported
XmlSerializer s = new XmlSerializer(typeof(ArrayList),
new Type[] { typeof(flex_format) });
TextReader r = new StreamReader("formats.xml");
formats_supported = (ArrayList)s.Deserialize(r);
r.Close();
OpenFileDialog dlg = new OpenFileDialog();
//Stuff the dialog's file filter with formats supported
foreach (flex_format format in formats_supported)
{
dlg.Filter += (dlg.Filter.Length>0?"|":"")+
format.description + "|*" + format.suffix;
}
if (dlg.ShowDialog() == DialogResult.OK)
{
load_list(dlg.FileName);
}
private void load_list(string file_name)
{
flex_format format = null;
//Determine the file format by file name suffix
foreach (flex_format fmt in formats_supported)
{
if (file_name.EndsWith(fmt.suffix))
{
format = fmt;
break;
}
}
listView1.Clear();
//Stuff the listview columns with field names
foreach(string field_name in format.entries)
{
listView1.Columns.Add(field_name);
}
//Now read the content of the input file
textBox1.Text = null;
StreamReader reader = new StreamReader(file_name);
while (true)
{
string line = reader.ReadLine();
textBox1.Text += line+"\r\n";
if(line == null || line.Length == 0) break;
//This is where the regular expression is used
Match match = new Regex(format.pattern).Match(line);
if(!match.Success) continue;
ListViewItem item = new ListViewItem(match.Groups[1].Value);
for (int i = 2; i < match.Groups.Count; i++)
{
item.SubItems.Add(match.Groups[i].Value);
}
listView1.Items.Add(item);
}
}
<anyType xsi:type="flex_format"
description="Car Speed Record Database"
suffix=".spd"
pattern="([^\t]+)\t([^\t]+)\t([\d\.]+)\s*(mph|km/h|m/s)">
<entries>
<entry>Make</entry>
<entry>Model</entry>
<entry>TopSpeed</entry>
<entry>Unit</entry>
</entries>
</anyType>
为什么使用正则表达式
类flex_format
将描述、文件后缀、正则表达式模式和字段名称数组存储在XML文件中。文件格式可以灵活到什么程度?就像正则表达式一样灵活。结合XML序列化,您将获得一个简洁的解决方案来支持灵活的文本格式。更重要的是,您可以在不更改应用程序的情况下轻松添加对新格式的支持。
修订历史
- [2009年7月2日] 对演示项目进行了小的更改。
- [2009年6月20日] 初始版本。