Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解析纯文本表_C#_Regex_Indexof - Fatal编程技术网

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

我正在尝试以纯文本格式解析一个表。该程序是在Visual Studio中使用C#编写的。我需要解析整个表并将数据插入数据库

下面是我将阅读的示例表:

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我会尝试优化代码!我会回来报到的!