3

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

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

我正在寻找以 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 行的行?

4

8 回答 8

4

而不是使用foreach()你可以使用 afor(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];
    }
}
于 2012-10-29T17:34:40.373 回答
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]);
    }
}
于 2012-10-29T17:37:53.833 回答
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 
    }
}
于 2012-10-29T17:43:27.547 回答
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)
                 }
                 );

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

在此处输入图像描述

于 2012-10-29T18:50:09.023 回答
0

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

于 2012-10-29T17:35:27.160 回答
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;
    }
}
于 2012-10-29T17:35:55.293 回答
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

    }  
}
于 2012-10-29T17:42:04.900 回答
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++;
}
于 2012-10-29T17:53:47.297 回答