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

时间:2012-10-29 17:30:39

标签: c# arrays text-files

我有一个文本文件,我加载到字符串数组中。该文件的内容如下所示:

  

OTI * IA * IX * NA~
REF * G1 * J EVERETTE~
REF * 11 * 0113722462~
  AMT * GW * 229.8~
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~
...

我正在寻找以OTI开头的行,如果它后跟“IA”,那么我需要从以REF * 11开头的行中获取10位数字。到目前为止,我有这个:

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
    }
}

我需要的线总是在当前OTI线之后的2行。如何从当前行访问2行的行?

8 个答案:

答案 0 :(得分:4)

您可以使用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];
    }
}

答案 1 :(得分:2)

这看起来像一个EDI文件!啊,EDI,记忆......

好消息是EDI文件是分隔的,就像大多数CSV文件格式一样。您可以使用任何标准CSV文件库将EDI文件加载到一个巨大的数组中,然后按位置迭代它。

我在这里发布了我的开源CSV库,如果它有用,请随时使用它。您只需将“星号”指定为分隔符:

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, '*', '\"');

此时,您可以正常迭代数据表。

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]);
    }
}

答案 2 :(得分:2)

怎么样:

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 
    }
}

答案 3 :(得分:1)

如果你想使用正则表达式来标记项目并创建动态实体,这里就是这样的模式

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)
                 }
                 );

这会产生一个像这样的项目列表,您可以将业务逻辑应用于:

enter image description here

答案 4 :(得分:0)

为什么不使用在System.Text.RegularExpressions中定义的Regex.Match或Regex.Matches来使用正则表达式匹配?您还可以查看字符串模式匹配算法,例如Knuth-Morris-Pratt算法。

答案 5 :(得分:0)

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;
    }
}

答案 6 :(得分:0)

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

    }  
}

答案 7 :(得分:0)

感谢大家......这就是我提出来的,但我也在阅读你的答案,因为我知道我会学到一些东西!再次感谢!

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++;
}