0

実際には、データ テーブルを使用して 4 つの列を設定し、この列がテキスト ファイルから値を取得するようにします。テキストファイルから特定の行を削除するために正規表現を使用しました。

私の目的は、データ テーブルを使用してグリッド上にテキスト ファイルを表示することです。そのため、最初にデータ テーブルを作成し、正規表現を使用して行 (プログラムで表示) を削除しようとしています。

ここに私の完全なコードを投稿します。

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

ファイルを解析するには、次のことが必要です。

  1. ファイルのテキストをデータ チャンクに分割します。PTC CUR TAX FARE BASISあなたの場合、チャンクはヘッダーと行で識別できますTOTAL。テキストを分割するには、次のように入力をトークン化する必要があります> (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 に答える
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;

(フィールドはコンマで区切られていると仮定)

編集:これはあなたのペーストビンで動作します:

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 に答える