C# 解析纯文本表
我正在尝试以纯文本格式解析一个表。该程序是在Visual Studio中使用C#编写的。我需要解析整个表并将数据插入数据库 下面是我将阅读的示例表:C# 解析纯文本表,c#,regex,indexof,C#,Regex,Indexof,我正在尝试以纯文本格式解析一个表。该程序是在Visual Studio中使用C#编写的。我需要解析整个表并将数据插入数据库 下面是我将阅读的示例表: ID Name Value1 Value2 Value3 Value4 //header 1 nameA 3.0 0.2 2 6.2 2 nameB 3 nameC
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
将不再收集正确的数据
此方法仅收集1、3和4的正确数据
方法2:
使用Regex
收集所有匹配项。我希望这可以按此顺序收集ID、名称、值1、值2、值3、值4
我的模式是(\d*?)\s\s\s+(.*?\s\s+(\d*\.\d*))\s\s+(\d*\.*\d*))\s\s+(\d*\..\d*)\s\s+(\d*\.\d*)
问题:收集的数据在某些行中向左移动。例如,在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
把这个文件当作一个固定长度的文件,你可以用索引和长度来定义每一列。定义了固定长度列后,只需使用
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;
}
好的,给你!使用此正则表达式模式:
^(?<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+)?)?$
注意:您必须将其匹配到任何一行,而不是整个文档!如果要对整个文档执行此操作,则必须添加“多行”修饰符(“m”)。您可以通过在regex模式的开头添加(?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+)?)?$
(?\d+)(?:\s{2,25})(?。+)(?:\s{2,45})(?\d+(?:\.\d+)(?:\s{2,33})(?\d+(?:\.\d+)(?:\s{2,14})(?\d+(?:\.\d+)(?:\.\s{2,19})(?\d+)(?:::\.\d+)$
值是否可以有空格?表中是否有空格(“”)?如果没有,你可以只读一行,把所有的空格分开,把所有的空格都整理出来strings@coolerfarmer想法是一样的,但不起作用,因为可能有空的细胞。因此,您不知道如何在4列上分配3个值。(除非你建立了一些容易出错的逻辑,通过计算中间的空格来确定。)@dognose所有数据都是用空格(“”)分隔的,值和名称可能都有空格。我只收集至少有1行的行value@dognose例如,ID3和ID8都有空单元格,但我仍然想收集其他值的数据。非常感谢!我试过你的正则表达式,它适用于我提供的示例,但是,当我将它插入实际数据时,它不起作用。这是实际数据“68苯甲醇6.0 0.4 1 7.4”中的一行,你能解释一下为什么它不能捕获并帮助我修改它吗?好的,我试试。你们能不能再给我发几行数据,这样我就可以用它们来测试了?@sora我更新了我的帖子。如果有效,请报告!它在我正在使用的regex模拟器上工作,我很确定它也能在我的程序中工作,我会在我的代码中实现它。非常感谢你@sora我会尝试优化代码!我会回来报到的!