简体   繁体   English

如何从文本文件中的另一行读取X行?

[英]How can I read X lines down from another line in a text file?

I have a text file that I load into a string array. 我有一个文本文件,我加载到一个字符串数组。 The contents of the file looks something like this: 该文件的内容如下所示:

OTI*IA*IX*NA~ OTI * IA * IX * NA〜
REF*G1*J EVERETTE~ REF * G1 * J EVERETTE~
REF*11*0113722462~ REF * 11 * 0113722462〜
AMT*GW*229.8~ AMT * GW * 229.8〜
NM1*QC*1*JENNINGS*PHILLIP~ NM1 * QC * 1 *詹宁斯* PHILLIP〜
OTI*IA*IX*NA~ OTI * IA * IX * NA〜
REF*G1*J EVERETTE~ REF * G1 * J EVERETTE~
REF*11*0113722463~ REF * 11 * 0113722463〜
AMT*GW*127.75~ AMT * GW * 127.75〜
NM1*QC*1*JENNINGS*PHILLIP~ NM1 * QC * 1 *詹宁斯* PHILLIP〜
OTI*IA*IX*NA~ OTI * IA * IX * NA〜
REF*G1*J EVERETTE~ REF * G1 * J EVERETTE~
REF*11*0113722462~ REF * 11 * 0113722462〜
AMT*GW*10.99~ AMT * GW * 10.99〜
NM1*QC*1*JENNINGS*PHILLIP~ NM1 * QC * 1 *詹宁斯* PHILLIP〜
... ...

I'm looking for the lines that start with OTI, and if it's followed by "IA" then I need to get the 10 digit number from the line that starts with REF*11. 我正在寻找以OTI开头的行,如果它后跟“IA”,那么我需要从以REF * 11开头的行中获取10位数字。 So far, I have this: 到目前为止,我有这个:

string[] readText = File.ReadAllLines("myfile.txt");

foreach (string s in readText) //string contains 1 line of text from above example
{
    string[] currentline = s.Split('*');

    if (currentline[0] == "OTI")
    {
        //move down 2 lines and grab the 10 digit
        //number from the line that starts with REF*11
    }
}

The line I need is always 2 lines after the current OTI line. 我需要的线总是在当前OTI线之后的2行。 How do I access the line that's 2 lines down from my current line? 如何从当前行访问2行的行?

Instead of using foreach() you can use a for(int index = 0; index < readText.Length; index++) Then you know the line you are accessing and you can easily say int otherIndex = index + 2 而不是使用foreach()你可以使用for(int index = 0; index < readText.Length; index++)然后你知道你正在访问的行,你可以很容易地说int otherIndex = index + 2

string[] readText = File.ReadAllLines("myfile.txt");

for(int index = 0; index < readText.Length; index++)
{
    string[] currentline = readText[index].Split('*');

    if (currentline[0] == "OTI")
    {
        //move down 2 lines and grab the 10 digit
        //number from the line that starts with REF*11
        int refIndex = index + 2;
        string refLine = readText[refIndex];
    }
}

This looks like an EDI file! 这看起来像一个EDI文件! Ahh, EDI, the memories... 啊,EDI,回忆......

The good news is that the EDI file is delimited, just like most CSV file formats. 好消息是EDI文件是分隔的,就像大多数CSV文件格式一样。 You can use any standard CSV file library to load the EDI file into a gigantic array, and then iterate through it by position. 您可以使用任何标准CSV文件库将EDI文件加载到一个巨大的数组中,然后按位置迭代它。

I published my open source CSV library here, feel free to use it if it's helpful. 我在这里发布了我的开源CSV库,如果它有用,请随时使用它。 You can simply specify the "asterisk" as the delimiter: 您可以简单地将“星号”指定为分隔符:

https://code.google.com/p/csharp-csv-reader/ https://code.google.com/p/csharp-csv-reader/

// This code assumes the file is on disk, and the first row of the file
// has the names of the columns on it
DataTable dt = CSVReader.LoadDataTable(myfilename, '*', '\"');

At this point, you can iterate through the datatable as normal. 此时,您可以正常迭代数据表。

for (int i = 0; i < dt.Rows.Count; i++) {
    if (dt.Rows[i][0] == "OTI") {
        Console.WriteLine("The row I want is: " + dt.Rows[i + 2][0]);
    }
}

What about: 关于什么:

string[] readText = File.ReadAllLines("myfile.txt");

for (int i = 0; i < readText.Length; i++)
{
    if (readText[i].StartsWith("OTI") && readText[i+2].StartsWith("REF*11")){
       string number = readText[i+2].Substring("REF*11".Length, 10);
       //do something 
    }
}

If you want to use regex to tokenize the items and create dynamic entities, here is such a pattern 如果您想使用正则表达式来标记项目并创建动态实体,这里就是这样的模式

string data = @"NM1*QC*1*JENNINGS*PHILLIP~
OTI*IA*IX*NA~
REF*G1*J EVERETTE~
REF*11*0113722463~
AMT*GW*127.75~
NM1*QC*1*JENNINGS*PHILLIP~
OTI*IA*IX*NA~
REF*G1*J EVERETTE~
REF*11*0113722462~
AMT*GW*10.99~
NM1*QC*1*JENNINGS*PHILLIP~";

string pattern = @"^(?<Command>\w{3})((?:\*)(?<Value>[^~*]+))+";

var lines = Regex.Matches(data, pattern, RegexOptions.Multiline)
                 .OfType<Match>()
                 .Select (mt => new
                 {
                    Op   = mt.Groups["Command"].Value,
                    Data = mt.Groups["Value"].Captures.OfType<Capture>().Select (c => c.Value)
                 }
                 );

That produces a list of items like this which you can apply your business logic to: 这会产生一个像这样的项目列表,您可以将业务逻辑应用于:

在此输入图像描述

Why dont you use regular expression matches using Regex.Match or Regex.Matches defined in System.Text.RegularExpressions? 为什么不使用在System.Text.RegularExpressions中定义的Regex.Match或Regex.Matches来使用正则表达式匹配? You can also look at string pattern matching algorithms such as the Knuth-Morris-Pratt algorithms. 您还可以查看字符串模式匹配算法,例如Knuth-Morris-Pratt算法。

string[] readText = File.ReadAllLines("myfile.txt");
foreach (string s in readText) //string contains 1 line of text from above example
{
    string[] currentline = s.Split('*');

    if (currentline[0] == "REF"&&currentline[1] == "11")
    {
        found=false;
        needed=current+2;
    }
}
string[] readText = File.ReadAllLines("myfile.txt");

for(int linenum = 0;linenum < readText.Length; linenum++) 
{
    string s = readText[linenum];

    string[] currentline = s.Split('*');

    if (currentline[0] == "OTI")
    {
        //move down 2 lines and grab the 10 digit
        linenum +=2;
        string refLine = readText[linenum];
        //number from the line that starts with REF*11

        // Extract your number here from refline

    }  
}

Thank guys .. this is what I came up with, but I'm also reading your answers as I KNOW I will learn something! 谢谢你们..这就是我想出来的,但我也在阅读你的答案,因为我知道我会学到一些东西! Thanks again! 再次感谢!

string[] readText = File.ReadAllLines("myfile.txt");

int i = 0;
foreach (string s in readText)
{
    string[] currentline = s.Split('*');

    if (currentline[0] == "OTI")
    {
        lbRecon.Items.Add(readText[i+2].Substring(8, 9));
    }
i++;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM