从C#中的分隔文件中读取行

时间:2016-02-23 23:51:28

标签: c# delimiter readfile

我有一个程序,我正在尝试将他们输入的信息记录到程序中并将其存储到各种模板文件中,因此可以轻松保存和重新加载。模板格式如下所示

#START#1 -- Contact#END#
#START#1 -- Error
2 -- Error
3 -- Error#END#
#START#1 -- Actions
2 -- Actions
3 -- Actions
4 -- Actions#END#
#START#1 -- Res
2 -- Res
3 -- Res#END#
#START#WorkedWith#END#
#START#3011#END#
#START#1 -- Details
2 -- Details
3 -- Details#END#

#START##END#标记之间的所有内容都是需要存储在不同变量中的值。

例如,第一个变量需要包含

1 -- Contact

第二个变量需要包含

1 -- Error
2 -- Error
3 -- Error

依此类推,直到第7个变量包含Details second。

最简单的方法是读取文件并将分隔符之间的数据存储到变量中?

提前致谢!

编辑:对于Sakura

代码:

string sInput = "";
using (var reader = new StreamReader(sTemplateFilePath))
{
    while (!reader.EndOfStream)
    {
        var line = reader.ReadLine();
        sInput = sInput + line;

    }
    reader.Close();
}
foreach (Match m in Regex.Matches(sInput, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
    foreach (var line in m.Groups[1].Value.Split('\n'))
    {
        switch (iLineCount)
        {
            case 0:
                sContactReason = line;
            break;

            case 1:
                sError = line;
            break;

            case 2:
                sActionsTaken = line;
            break;

            case 3:
                sResolution = line;
            break;

            case 4:
                sL3 = line;
            break;

            case 5:
                sKB = line;
            break;

            case 6:
                sDetails = line;
            break;
        }

        iLineCount++;

    }
}

输出:

1 -- Contact

1 -- Error2 -- Error3 -- Error

1 -- Actions2 -- Actions3 -- Actions4 -- Actions

1 -- Res2 -- Res3 -- Res

WorkedWith

3011

1 -- Details2 -- Details3 -- Details

5 个答案:

答案 0 :(得分:2)

    static void Main()
    {
        string s = @"#START#1 -- Contact#END#
#START#1 -- Error
2 -- Error
3 -- Error#END#
#START#1 -- Actions
2 -- Actions
3 -- Actions
4 -- Actions#END#
#START#1 -- Res
2 -- Res
3 -- Res#END#
#START#WorkedWith#END#
#START#3011#END#
#START#1 -- Details
2 -- Details
3 -- Details#END#";

        int k = -1;
        foreach (Match m in Regex.Matches(s, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
        {
            Console.WriteLine("Variable " + ++k + " is:\n" + m.Groups[1].Value);
            Console.WriteLine();
        }
        Console.ReadLine();
    }

"#START#(.*?)#END#"会为#START##END#"之间的任何内容匹配。

结果:

Variable 0 is:
1 -- Contact

Variable 1 is:
1 -- Error
2 -- Error
3 -- Error

Variable 2 is:
1 -- Actions
2 -- Actions
3 -- Actions
4 -- Actions

Variable 3 is:
1 -- Res
2 -- Res
3 -- Res

Variable 4 is:
WorkedWith

Variable 5 is:
3011

Variable 6 is:
1 -- Details
2 -- Details
3 -- Details

如果要将结果拆分为行,可以使用split来获取所需的变量。

int k = -1;
foreach (Match m in Regex.Matches(s, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
    k++;
    int k2 = -1;
    Console.WriteLine("Variable " + k + ":");
    foreach (var line in m.Groups[1].Value.Split('\n'))
    {
        Console.WriteLine("Line " + ++k2 + ": " + line);
    }
    Console.WriteLine();
}

结果:

Variable 0:
Line 1: 1 -- Contact

Variable 1:
Line 1: 1 -- Error
Line 3: 2 -- Error
Line 5: 3 -- Error

Variable 2:
Line 1: 1 -- Actions
Line 3: 2 -- Actions
Line 5: 3 -- Actions
Line 7: 4 -- Actions

Variable 3:
Line 1: 1 -- Res
Line 3: 2 -- Res
Line 5: 3 -- Res

Variable 4:
Line 1: WorkedWith

Variable 5:
Line 1: 3011

Variable 6:
Line 1: 1 -- Details
Line 3: 2 -- Details
Line 5: 3 -- Details

编辑:

以下整个代码是浪费,而且是错误的。

string sInput = "";
using (var reader = new StreamReader(sTemplateFilePath))
{
    while (!reader.EndOfStream)
    {
        var line = reader.ReadLine();
        sInput = sInput + line;

    }
    reader.Close();
}

将其更改为:

string sInput = File.ReadAllText(sTemplateFilePath);

修改

  

@Sakura我需要将每个正则表达式匹配分配给另一个变量。所以   第一场比赛进入Variable1,第二场比赛进入   Variable2,第三个匹配在Variable3中。那有意义吗? -

这是你需要的吗?

int k = 0;
foreach (Match m in Regex.Matches(sInput, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
    k++;
    switch (k)
    {
        case 1:
            var1 = m.Groups[1].Value;
            break;
        case 2:
            //var2...
            break;
    }
    foreach (var line in m.Groups[1].Value.Split('\n'))
    {
        switch (iLineCount)
        {
        }
    }
}

答案 1 :(得分:0)

我可能会使用带有捕获组的Regex类来获取#BEGIN##END#分隔符之间的内容。我猜你想丢弃文本。正则表达式看起来像:

#BEGIN#(.*?)#END#

捕获组(#1)由括号表示,并包含分隔文本。您可以通过将内容加载到字符串缓冲区中来迭代内容,当没有剩余匹配时此正则表达式终止。

答案 2 :(得分:0)

使用CSV文件。它们实际上是为了你想要做的而制作的。如果您不想使用逗号,则可以通过在文件中指定其他属性来更改分隔符。

您可以使用行来分隔多个,就像您在帖子中的自定义分隔符之间一样。如果我错过了什么,我道歉。

答案 3 :(得分:0)

编写自己的解析器。这很简单。在这里,我假设#START##END#各自独立(您可以使用搜索和替换或C#代码强制执行)

    private List<List<string>> parseData(string data)
    {
        List<List<string>> allValues = new List<List<string>>();
        List<string> currentValues = null;

        // Assume that each line has only one entry
        foreach (var line in data.Split(new [] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries))
        {
            if (line == "#START#")
            {
                currentValues = new List<string>();
            }
            else if (line == "#END#")
            {
                allValues.Add(currentValues);
            }
            else
            {
                currentValues.Add(line);
            }
        }
        return allValues;
    }

答案 4 :(得分:0)

与指向正则表达式或编写自己的解析器的其他答案相反,我建议使用FileHelpers library

读取分隔文件会有点像这样;首先定义一个匹配单个文件记录的类:

[DelimitedRecord("|")]
public class Orders
{
    public int OrderID;

    public string CustomerID;

    [FieldConverter(ConverterKind.Date, "ddMMyyyy")]
    public DateTime OrderDate;

    [FieldConverter(ConverterKind.Decimal, ".")] // The decimal separator is .
    public decimal Freight;
}

阅读文件:

var engine = new FileHelperEngine<Orders>();
var records = engine.ReadFile("Input.txt");

foreach (var record in records)
{
    Console.WriteLine(record.CustomerID);
    Console.WriteLine(record.OrderDate.ToString("dd/MM/yyyy"));
    Console.WriteLine(record.Freight);
}