0

实际上我使用数据表设置了四列,我希望该列从文本文件中检索值。我使用正则表达式从文本文件中删除特定行。

我的目标是我想使用数据表在网格上显示文本文件,所以首先我尝试使用正则表达式创建数据表并删除行(在程序中显示)。

在这里,我发布了我的完整代码。

namespace class
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        { 
            StreamReader sreader = File.OpenText(@"C:\FareSearchRegex.txt");
            string line;
            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add("PTC");
            dt.Columns.Add("CUR");
            dt.Columns.Add("TAX");
            dt.Columns.Add("FARE BASIS");
            while ((line = sreader.ReadLine()) != null)
            {
                var pattern = "---------- RECOMMENDATION 1 OF 3 IN GROUP 1 (USD 168.90)----------";
                var result = Regex.Replace(line,pattern," ");
                dt.Rows.Add(line);    
            }
        }
    }

    class Class1
    {
        string PTC;
        string CUR;
        float TAX;

        public string gsPTC
        {
            get{ return PTC; }
            set{ PTC = value; }
        }

        public string gsCUR
        {
            get{ return CUR; }
            set{ CUR = value; }
        }

        public float gsTAX
        {
            get{ return TAX; }
            set{ TAX = value; }
        }
    }
}
4

2 回答 2

0

如果您的格式是严格的(例如总是 4 列)并且您只想删除这一完整行,我认为没有任何理由使用正则表达式:

var rows = File.ReadLines(@"C:\FareSearchRegex.txt")
    .Where(l => l != "---------- RECOMMENDATION 1 OF 3 IN GROUP 1 (USD 168.90)----------")
    .Select(l => new { line = l, items = l.Split(','), row = dt.Rows.Add() });
foreach (var x in rows)
    x.row.ItemArray = x.items;

(假设字段用逗号分隔)

编辑:这适用于您的 pastebin:

string header = "  PTC       CUR                 TAX           FARE BASIS";
bool takeNextLine = false;
foreach (string line in File.ReadLines(@"C:\FareSearchRegex.txt"))
{
    if (line.StartsWith(header))
        takeNextLine = true;
    else if (takeNextLine)
    {
        var tokens = line.Split(new[] { @"   " }, StringSplitOptions.RemoveEmptyEntries);
        dt.Rows.Add().ItemArray = tokens.Where((t, i) => i != 2).ToArray();
        takeNextLine = false;
    }
}

(因为您有一个要从结果中排除的空列,所以我使用了笨拙且可能容易出错(?)的查询Where((t, i) => i != 2)

于 2013-01-28T13:23:26.717 回答
0

要解析文件,您需要:

  1. 将文件的文本拆分为数据块。在您的情况下,一个块可以通过标题PTC CUR TAX FARE BASISTOTAL行来识别。要拆分文本,您需要按如下方式标记输入>(i)定义一个正则表达式以匹配标题,(ii)定义一个正则表达式以匹配Total行(页脚);使用 (i) 和 (ii) 您可以按外观索引的顺序连接它们并确定每个块的总大小(参见(x,y)=>new{StartIndex = x.Match.Index, EndIndex = y.Match.Index + y.Match.Length})下面的行)。使用String.Substring方法来分离块。

  2. 从每个单独的块中提取数据。知道数据是按行拆分的,您只需遍历块中的所有行(忽略页眉和页脚)并处理每一行。

这段代码应该有帮助:

string file = @"C:\FareSearchRegex.txt";
string text = File.ReadAllText(file);
var headerRegex = new Regex(@"^(\)>)?\s+PTC\s+CUR\s+TAX\s+FARE BASIS$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
var totalRegex = new Regex(@"^\s+TOTAL[\w\s.]+?$",RegexOptions.IgnoreCase | RegexOptions.Multiline);
var lineRegex = new Regex(@"^(?<Num>\d+)?\s+(?<PTC>[A-Z]+)\s+\d+\s(?<Cur>[A-Z]{3})\s+[\d.]+\s+(?<Tax>[\d.]+)",RegexOptions.IgnoreCase | RegexOptions.Multiline);
var dataIndices = 
    headerRegex.Matches(text).Cast<Match>()
        .Select((m, index) => new{ Index = index, Match = m })
        .Join(totalRegex.Matches(text).Cast<Match>().Select((m, index) => new{ Index = index, Match = m }),
            x => x.Index,
            x => x.Index,
            (x, y) => new{ StartIndex = x.Match.Index, EndIndex = y.Match.Index + y.Match.Length });
var items = dataIndices
    .Aggregate(new List<string>(), (list, x) =>
    {
        var item = text.Substring(x.StartIndex, x.EndIndex - x.StartIndex);
        list.Add(item);
        return list;
    });

var result = items.SelectMany(x => 
{
    var lines = x.Split(new string[]{Environment.NewLine, "\r", "\n"}, StringSplitOptions.RemoveEmptyEntries);
    return lines.Skip(1) //Skip header
        .Take(lines.Length - 2) // Ignore footer
        .Select(line =>
        {
            var match = lineRegex.Match(line);
            return new
            {
                Ptc = match.Groups["PTC"].Value,
                Cur = match.Groups["Cur"].Value,
                Tax = Convert.ToDouble(match.Groups["Tax"].Value)
            };
        });
});
于 2013-01-28T15:12:05.007 回答