在多个数据后搜索文本文件,并将它们填充到数据网格视图中

本文关键字:数据 填充 网格 视图 数据网 搜索 文本 文件 | 更新日期: 2023-09-27 17:52:51

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

文本文件看起来像这样(这只是1000行中的1行):

3016XY1234567891111111ABCDEFGHIJKabcdef+0000001029916XY1111111123456789ABCDEFGHIJKabcdef+00000003801

现在这些是2条记录,我需要从每条记录中获得2个数据。

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

       Value from the example: XY1234567891111111
    
  2. "价格"-即加号后的11位数字值。最后两位数字指定美分的金额。

       Value from the example: 102,99$
    

我需要这两个数据是在同一行在我的数据网格视图,也为所有其他数据在这个文本文件。

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

我尝试了几种可能性来搜索和计算这些值,但现在没有任何成功。我也不确定如何获得数据到特定的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);

提前感谢!

在多个数据后搜索文本文件,并将它们填充到数据网格视图中

创建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;
    }
}
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();

如果您需要整个文本文件作为字符串,您可以使用.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)));
            }
      }
}

你将需要一些模型

public class YourModel
{
    public YourModel(string xy, string price)
    {
        float forTest = 0;
        XYNUMBER = xy;
        string addForParse = string.Format("{0}.{1}", price.Substring(0, price.Length - 2), price.Substring(price.Length - 2, 2));
        if (float.TryParse(addForParse, out forTest)) 
        {
            Price = forTest;
        }
    }
    public string XYNUMBER { get; set; }
    public float Price { get; set; }
}

之后你可以将它绑定到gridview。

考虑到"数据对"每行都是可变的(并且可以被截断到下一行),最好使用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;

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

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;

你的'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>