C#在多个数据之后搜索文本文件并将其填充到数据网格视图中

时间:2016-06-29 06:35:04

标签: c#

我从文本文件中获取数据。文件本身已由ReadAllLines插入并转换为字符串 - 这对我来说很好用,我用MessageBox检查了内容。

Textfile看起来像这样(这只是大约一行的1行):

3016XY1234567891111111ABCDEFGHIJKabcdef+0000001029916XY1111111123456789ABCDEFGHIJKabcdef+00000003801

现在这些是2条记录,每条记录需要2条数据。

  1. " XY数" - 这是前16位数字" 16XY" (16XY总是相同的值)

       Value from the example: XY1234567891111111
    
  2. " Price" - 这是加号后的11位数值。最后2位数字指定分数。

       Value from the example: 102,99$
    
  3. 我需要这两个数据在我的Datagrid视图中的同一行以及此文本文件中的所有其他数据。

    我能想象的是编写一个代码,在" 16XY"之后搜索字符串。并计算接下来的16位数 - 与搜索"加"的价格相同并计算接下来的11位数。在这种情况下,我需要忽略文件的第一行,因为大约有10x" +"。

    我尝试了几种可能性来搜索和计算这些值,但现在却没有任何成功。我也不确定如何将数据导入特定的Datagrid视图。

    这就是我现在要展示的全部内容:

    List<List<string>> groups = new List<List<string>>();
                        List<string> current = null;
                        foreach (var line in File.ReadAllLines(path))
                        {
                            if (line.Contains("") && current == null)
                                current = new List<string>();                              
                            else if (line.Contains("") && current != null)
                            {
                                groups.Add(current);
                                current = null;
                            }
                            if (current != null)
                                current.Add(line);
                        }
    
                    //array
    
                    string output = string.Join(Environment.NewLine, current.ToArray());
    
                    //string
    
                    string final = string.Join("", output.ToCharArray());
                    MessageBox.Show(output);
    

    提前致谢!

5 个答案:

答案 0 :(得分:2)

创建classstruct来保存数据

public class Data
{
    String XYValue { set; get; }
    Decimal Price { set; get; }
}

然后读取逻辑(您可能需要添加更多检查)

string decimalSeperator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
List<Data> results = new List<Data>();
foreach(string line in File.ReadAllLines(path).Skip(1))
{
    if (line == null)
        continue;

    int indexOfNextXY = 0;
    while (true)
    {
        int indexOfXY = line.IndexOf("16XY", indexOfNextXY) + "16XY".Length;
        int indexOfPlus = line.IndexOf("+", indexOfXY + 16) + "+".Length;
        indexOfNextXY = line.IndexOf("16XY", indexOfPlus);

        string xyValue = line.Substring(indexOfXY - 2, 18); // -2 to get the XY part
        string price = indexOfNextXY < 0 ? line.Substring(indexOfPlus) : line.Substring(indexOfPlus, indexOfNextXY - indexOfPlus);

        string intPart = price.Substring(0, price.Length - 2);
        string decimalPart = price.Substring(price.Length - 2);
        price = intPart  + decimalSeperator + decimalPart;


        results.Add(new Data (){ XYValue = xyValue, Price = Convert.ToDecimal(price) });

        if (indexOfNextXY < 0)
            break;
    }
}

答案 1 :(得分:0)

考虑使用Split方法。从示例数据中,我注意到有&#34; 16XY&#34;每个值之间。所以像这样:

var data = "3016XY1234567891111111ABCDEFGHIJKabcdef+0000001029916XY1111111123456789ABCDEFGHIJKabcdef+00000003801";

var records = data.Split(new string[] { "16XY" }, StringSplitOptions.RemoveEmptyEntries);

给定示例数据,这将返回以下数组:

[0]: "30"
[1]: "1234567891111111ABCDEFGHIJKabcdef+00000010299"
[2]: "1111111123456789ABCDEFGHIJKabcdef+00000003801"

现在,计算每个字符串中的字符并在代码中赋予它们含义会更容易。

因此,我们知道有价值的数据由 + 分隔。让我们进一步拆分并填充Dictionary<string, double>

var parsed = new Dictionary<string, double>(records.Length - 1);

foreach (var pairX in records.Skip(1))
{
    var fields = pairX.Split('+');
    var cents = double.Parse(fields[1]);
    parsed.Add(fields[0], cents / 100);
}

// Now you bind to the GridView
gv.DataSource = parsed;

您的&#39; GridView`声明应如下所示:

<asp:GridView ID="gv" runat="server" AutoGenerateColumns="false">
    <Columns>
        <asp:BoundField DataField="Key" HeaderText="ID" />
        <asp:BoundField DataField="Value" HeaderText="Price" />
    </Columns>
</asp:GridView>

答案 2 :(得分:0)

var regex = new Regex(@"\+(\d+)(\d{2})16(XY\d{16})");
var q =
    from e in File.ReadLines("123.txt")
    let find = regex.Match(e)
    where find.Success
    select new
    {
        price = double.Parse(find.Groups[1].Value) + (double.Parse(find.Groups[2].Value) / 100),
        value = find.Groups[3]
    };

dataGridView1.DataSource = q.ToList();

答案 3 :(得分:0)

如果您需要将整个文本文件作为字符串,则可以使用enum方法对其进行操作。

行动将如下所示:

.Split

你需要一些模型

var values = final.Split(new string[] { "16XY" }, StringSplitOptions.RemoveEmptyEntries).ToList();

List <YourModel> models = new List<YourModel>();

foreach (var item in values)
{
      if (item.IndexOf('+') > 0)
      {
            var itemSplit = item.Split('+');
            if (itemSplit[0].Length > 15 &&
                itemSplit[1].Length > 10)
            {
                 models.Add(new YourModel(itemSplit[0].Substring(0, 16), itemSplit[1].Substring(0, 11)));
            }
      }
}

之后,您可以将其绑定到gridview。

答案 4 :(得分:0)

鉴于“数据对”每行都是可变的(并且可以截断到下一行),最好使用File.ReadAllText()。这将为您提供单个字符串,消除截断问题。

var data = File.ReadAllText(path);

定义包含数据的模型:

public class Item {
  public string XYNumber { get; set; }
  public double Price { get; set; }
}

然后,您可以使用正则表达式查找匹配项并将其存储在列表中:

var list = List<Item>();
var regex = new Regex(@"(XY\d{16})\w+\+(\d{11})");
var match = regex.Match(data);
while (match.Success) {
  var ps = match.Group[1].Captures[0].Value.Insert(9, ".");
  list.Add(new Item { 
    XYNumber = match.Group[0].Captures[0].Value,
    Price = Convert.ToDouble(ps)
  });
  match = match.NextMatch();
}

该列表还可以用作网格视图的数据源:

gridView.DataSource = list;