我需要解析一个文件,但数据是一种奇怪的格式,我不熟悉解析。
数据总是这样格式化。字段名称位于左侧,数据位于“=”右侧,所有字段始终按此顺序排列。
档案数据:
Report 1 of 1
job_name = JOBNAME
job_no = JOB99999 job_id = 6750
rprt_id = 27811
rprt_name = SOMEDATA.SOMEUSER.JOBNAME.JOB099999.0000000.?
ftp_size = 999999
job_group_name = 1
clas = Z
form = 9999
user_id = SOMEUSER
我的第一直觉是做这样的事......
'New up a class created to hold the data'
Dim NFOData As New NFOData
'Create counter for line numbers'
Dim i As Integer = 1
Using sr As New StreamReader(filename)
While Not sr.EndOfStream
Dim line As String = sr.ReadLine
Select Case i
Case 2
NFOData.JobName = line.Substring(11)
Case 3
NFOData.JobNo = line.Substring(9)
Case 4
'snipped to save space'
End Select
i += 1
End While
End Using
这对我来说似乎不是很干净或优雅。
是否有一种更优雅的方式来处理像这样的解析文件?
答案 0 :(得分:1)
以下代码是C#,但应该很容易转换为VB。它使用字典将文件中的密钥映射到PropertyInfo
,然后使用反射设置值。缺少对第一行的处理,可能还有一些小问题。
Dictionary<String, PropertyInfo> map = new Dictionary<String, PropertyInfo>();
map["job_name"] = typeof(NFOData).GetProperty("JobName");
map["job_no"] = typeof(NFOData).GetProperty("JobNo");
// ....
NFOData nfoData = new NfOData();
using (StreamReader sr = new StreamReader(filename))
{
String line;
while ((line = sr.ReadLine()) != null)
{
String[] parts = line.Split(new[] {" = "}, StringSplitOptions.None);
map[parts[0]].SetValue(nfoData, parts[1], null);
}
}
答案 1 :(得分:0)
我可能会读取每一行,将其拆分为=,并将其放在字符串哈希中,其中字段名称是键,因此您可以通过fieldname引用它。
答案 2 :(得分:0)
这是C#(抱歉,我没有VB)并且没有任何类型的错误检查,但是像KeyValuePairs列表那样......
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace NVP
{
class Program
{
static void Main(string[] args)
{
var nvp = new List<KeyValuePair<string, string>>();
var fs = File.Open(@"c:\temp\report.txt", FileMode.Open);
var sw = new StreamReader(fs);
while (!sw.EndOfStream)
{
var line = sw.ReadLine();
if (!String.IsNullOrEmpty(line) && line.Contains("="))
{
var tmp = line.Split('=');
nvp.Add( new KeyValuePair<string, string>(tmp[0], tmp[1]));
}
}
sw.Close();
fs.Close();
var str = nvp.Select(kv => kv.Key + " " + kv.Value);
str.ToList().ForEach(Console.WriteLine);
Console.ReadLine();
}
}
}