实际上我使用数据表设置了四列,我希望此列从文本文件中检索值。我使用正则表达式从文本文件中删除特定行。
我的目标是我想使用数据表在网格上显示文本文件,所以首先我尝试使用正则表达式创建数据表并删除行(在程序中显示)。
我在这里发布完整的代码。
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; }
}
}
}
答案 0 :(得分: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)
)
答案 1 :(得分:0)
要解析您需要的文件:
将文件文本拆分为数据块。在您的情况下,块可以通过标题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
方法分隔块。
从每个单独的块中提取数据。知道数据是按行分割的,你只需要迭代一个块中的所有行(忽略页眉和页脚)并处理每一行。
此代码应该有所帮助:
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)
};
});
});