我正在尝试以纯文本格式解析表格。该程序是使用C#在Visual Studio中编写的。我需要解析表并将数据插入数据库。
以下是我将要阅读的示例表:
ID Name Value1 Value2 Value3 Value4 //header
1 nameA 3.0 0.2 2 6.2
2 nameB
3 nameC 2.9 3.0 7.3
4 nameD 1.5 3.0 1.8 1.1
5 nameE
6 nameF 1.2 2.4 3.3 2.5
7 nameG 3.0 3.2 2.1 4.5
8 nameH 88 12.4 28.9
在示例中,我需要捕获id 1,3,4,6,7和8的数据。
我想到了两种方法来解决这个问题,但它们都没有100%工作。
方法1:
通过读入标题,我可以获得每列的起始索引。然后,我将使用Substring
收集每行的数据。
ISSUE:一旦超过某一行(我不知道何时发生这种情况),列移位,Substring
将不再收集正确的数据。
此方法仅收集1,3和4的正确数据。
方法2:
使用Regex
收集所有匹配项。我希望这可以按此顺序收集ID,Name,Value1,Value2,Value3,Value4。
我的模式是(\d*?)\s\s\s+(.*?)\s\s\s+(\d*\.*\d*)\s\s\s+(\d*\.*\d*)\s\s\s+(\d*\.*\d*)\s\s\s+(\d*\.*\d*)
ISSUE:收集的数据会向左移动一些行。例如,在ID 3上,Value2
应为空,但正则表达式将为Value2 = 3.0
,Value3 = 7.3
和Value4 = blank
。对于ID 8也是如此。
问题:
如何读取整个表格并正确解析它们?
(1)我不知道从哪一行开始移动值
(2)我不知道它将被转移多少个细胞以及它们是否一致。
其他信息
该表位于PDF文件中,我将PDF转换为文本文件,因此我可以读取数据。当表格跨越多个页面时,会发生移位数据,但这种情况并不一致。
修改
以下是一些实际数据:
68 BENZYL ALCOHOL 6.0 0.4 1 7.4
91 EVERNIA PRUNASTRI (OAK MOSS) 34 3 3 10
22 test 2323 23 12
答案 0 :(得分:1)
如何将此文件视为固定长度文件,您可以在其中按索引和长度定义每个列。定义固定长度列后,您只需使用Substring
获取列的值,然后Trim
进行清理即可。
您可以将所有这些包装在Linq语句中以投影到匿名类型并过滤所需的ID。
这样的事情:
static void Main(string[] args)
{
int[] select = new int[] { 1, 3, 4, 6, 7, 8 };
string[] lines = File.ReadAllLines("TextFile1.txt");
var q = lines.Skip(1).Select(l => new {
Id = Int32.Parse(GetValue(l, 0, 6)),
Name = GetValue(l, 6, 11),
Value1 = GetValue(l, 17, 11),
Value2 = GetValue(l, 28, 13),
Value3 = GetValue(l, 41, 14),
Value4 = GetValue(l, 55, 13),
}).Where(o => select.Contains(o.Id));
var r = q.ToArray();
}
static string GetValue(string line, int index, int length)
{
string value = null;
int lineLength = line.Length;
// Take as much of the line as we can up to column length
if(lineLength > index)
value = line.Substring(index, Math.Min(length, lineLength - index)).Trim();
// Return null if we just have whitespace
return String.IsNullOrWhiteSpace(value) ? null : value;
}
答案 1 :(得分:1)
注意:您必须将此匹配到任何一行,而不是整个文档!如果您想为整个文档执行此操作,则必须添加多行'修饰符(' m')。您可以通过在正则表达式模式的开头添加(?m)
来完成此操作!
修改强>
您提供了一些实际数据。这是我更新的正则表达式模式:
^(?<id>\d+)(?:\s{2,25})(?<name>.+?)(?:\s{2,45})(?<val1>\d+(?:\.\d+)?)?(?:\s{2,33})(?<val2>\d+(?:\.\d+)?)?(?:\s{2,14})(?<val3>\d+(?:\.\d+)?)?(?:\s{2,19})(?<val4>\d+(?:\.\d+)?)?$