C# 从C语言中的分隔文件中读取行#
我有一个程序,我试图有能力采取他们输入到程序的信息,并将其存储到一个模板文件的排序,所以它可以被保存和重新加载很容易。模板格式如下所示C# 从C语言中的分隔文件中读取行#,c#,delimiter,readfile,C#,Delimiter,Readfile,我有一个程序,我试图有能力采取他们输入到程序的信息,并将其存储到一个模板文件的排序,所以它可以被保存和重新加载很容易。模板格式如下所示 #START#1 -- Contact#END# #START#1 -- Error 2 -- Error 3 -- Error#END# #START#1 -- Actions 2 -- Actions 3 -- Actions 4 -- Actions#END# #START#1 -- Res 2 -- Res 3 -- Res#END# #START#Wo
#START#1 -- Contact#END#
#START#1 -- Error
2 -- Error
3 -- Error#END#
#START#1 -- Actions
2 -- Actions
3 -- Actions
4 -- Actions#END#
#START#1 -- Res
2 -- Res
3 -- Res#END#
#START#WorkedWith#END#
#START#3011#END#
#START#1 -- Details
2 -- Details
3 -- Details#END#
#START#
和#END#
标记之间的所有内容都是需要存储在不同变量中的值
int k = -1;
foreach (Match m in Regex.Matches(s, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
k++;
int k2 = -1;
Console.WriteLine("Variable " + k + ":");
foreach (var line in m.Groups[1].Value.Split('\n'))
{
Console.WriteLine("Line " + ++k2 + ": " + line);
}
Console.WriteLine();
}
例如,第一个变量需要包含
1 -- Contact
第二个变量需要包含
1 -- Error
2 -- Error
3 -- Error
依此类推,直到第七个变量包含第二个细节
读取文件并将分隔符之间的数据存储到变量中最简单的方法是什么
提前谢谢
编辑:樱花
代码:
string sInput = "";
using (var reader = new StreamReader(sTemplateFilePath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
sInput = sInput + line;
}
reader.Close();
}
foreach (Match m in Regex.Matches(sInput, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
foreach (var line in m.Groups[1].Value.Split('\n'))
{
switch (iLineCount)
{
case 0:
sContactReason = line;
break;
case 1:
sError = line;
break;
case 2:
sActionsTaken = line;
break;
case 3:
sResolution = line;
break;
case 4:
sL3 = line;
break;
case 5:
sKB = line;
break;
case 6:
sDetails = line;
break;
}
iLineCount++;
}
}
输出:
1 -- Contact
1 -- Error2 -- Error3 -- Error
1 -- Actions2 -- Actions3 -- Actions4 -- Actions
1 -- Res2 -- Res3 -- Res
WorkedWith
3011
1 -- Details2 -- Details3 -- Details
我可能会使用带有捕获组的
Regex
类来获取#BEGIN
和#END
分隔符之间的内容。我猜你想放弃文本,否则。正则表达式看起来像:
#开始#(.*)#结束#
捕获组(#1)由括号表示,将包含分隔文本。您可以通过将内容加载到字符串缓冲区来迭代内容,当没有剩余的匹配项时,此正则表达式终止
static void Main()
{
string s = @"#START#1 -- Contact#END#
#START#1 -- Error
2 -- Error
3 -- Error#END#
#START#1 -- Actions
2 -- Actions
3 -- Actions
4 -- Actions#END#
#START#1 -- Res
2 -- Res
3 -- Res#END#
#START#WorkedWith#END#
#START#3011#END#
#START#1 -- Details
2 -- Details
3 -- Details#END#";
int k = -1;
foreach (Match m in Regex.Matches(s, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
Console.WriteLine("Variable " + ++k + " is:\n" + m.Groups[1].Value);
Console.WriteLine();
}
Console.ReadLine();
}
“#开始#(.*)#结束#”(
将为您匹配#开始#
和#结束#“
之间的任何内容
结果:
Variable 0 is:
1 -- Contact
Variable 1 is:
1 -- Error
2 -- Error
3 -- Error
Variable 2 is:
1 -- Actions
2 -- Actions
3 -- Actions
4 -- Actions
Variable 3 is:
1 -- Res
2 -- Res
3 -- Res
Variable 4 is:
WorkedWith
Variable 5 is:
3011
Variable 6 is:
1 -- Details
2 -- Details
3 -- Details
Variable 0:
Line 1: 1 -- Contact
Variable 1:
Line 1: 1 -- Error
Line 3: 2 -- Error
Line 5: 3 -- Error
Variable 2:
Line 1: 1 -- Actions
Line 3: 2 -- Actions
Line 5: 3 -- Actions
Line 7: 4 -- Actions
Variable 3:
Line 1: 1 -- Res
Line 3: 2 -- Res
Line 5: 3 -- Res
Variable 4:
Line 1: WorkedWith
Variable 5:
Line 1: 3011
Variable 6:
Line 1: 1 -- Details
Line 3: 2 -- Details
Line 5: 3 -- Details
若要将结果拆分为行,可以使用“拆分”获得所需的变量
int k = -1;
foreach (Match m in Regex.Matches(s, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
k++;
int k2 = -1;
Console.WriteLine("Variable " + k + ":");
foreach (var line in m.Groups[1].Value.Split('\n'))
{
Console.WriteLine("Line " + ++k2 + ": " + line);
}
Console.WriteLine();
}
结果:
Variable 0 is:
1 -- Contact
Variable 1 is:
1 -- Error
2 -- Error
3 -- Error
Variable 2 is:
1 -- Actions
2 -- Actions
3 -- Actions
4 -- Actions
Variable 3 is:
1 -- Res
2 -- Res
3 -- Res
Variable 4 is:
WorkedWith
Variable 5 is:
3011
Variable 6 is:
1 -- Details
2 -- Details
3 -- Details
Variable 0:
Line 1: 1 -- Contact
Variable 1:
Line 1: 1 -- Error
Line 3: 2 -- Error
Line 5: 3 -- Error
Variable 2:
Line 1: 1 -- Actions
Line 3: 2 -- Actions
Line 5: 3 -- Actions
Line 7: 4 -- Actions
Variable 3:
Line 1: 1 -- Res
Line 3: 2 -- Res
Line 5: 3 -- Res
Variable 4:
Line 1: WorkedWith
Variable 5:
Line 1: 3011
Variable 6:
Line 1: 1 -- Details
Line 3: 2 -- Details
Line 5: 3 -- Details
编辑:
下面的全部代码都是浪费,而且是错误的
string sInput = "";
using (var reader = new StreamReader(sTemplateFilePath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
sInput = sInput + line;
}
reader.Close();
}
将其更改为:
string sInput = File.ReadAllText(sTemplateFilePath);
编辑
@Sakura我需要将每个正则表达式匹配赋给不同的变量 第一个匹配进入变量1,第二个匹配进入变量1 变量2,第三个匹配在变量3中。这有意义吗?- 这是你需要的吗
int k = 0;
foreach (Match m in Regex.Matches(sInput, "#START#(.*?)#END#", RegexOptions.Singleline | RegexOptions.Compiled))
{
k++;
switch (k)
{
case 1:
var1 = m.Groups[1].Value;
break;
case 2:
//var2...
break;
}
foreach (var line in m.Groups[1].Value.Split('\n'))
{
switch (iLineCount)
{
}
}
}
使用CSV文件。它们实际上是为您尝试执行的操作而创建的。如果您不想使用逗号,则始终可以通过在文件中指定其他属性来更改分隔符
您可以使用行来分隔倍数,就像您在帖子中自定义分隔符之间一样。如果我遗漏了什么,我很抱歉。编写您自己的解析器。这非常简单。这里我假设
#START#
和#END#
都在自己的行上(您可以使用搜索和替换或C代码强制执行)
私有列表解析数据(字符串数据)
{
List allValues=new List();
List currentValues=null;
//假设每行只有一个条目
foreach(data.Split(new[]{“\r\n”},StringSplitOptions.RemoveEmptyEntries)中的变量行)
{
如果(行=“#开始#”)
{
currentValues=新列表();
}
如果(行=“#结束#”)
{
添加(当前值);
}
其他的
{
currentValues.Add(行);
}
}
返回所有值;
}
与其他指向regex或编写自己的解析器的答案相反,我建议使用
读取带分隔符的文件有点像这样;首先定义一个与单个文件记录匹配的类:
[DelimitedRecord("|")]
public class Orders
{
public int OrderID;
public string CustomerID;
[FieldConverter(ConverterKind.Date, "ddMMyyyy")]
public DateTime OrderDate;
[FieldConverter(ConverterKind.Decimal, ".")] // The decimal separator is .
public decimal Freight;
}
正在读取文件:
var engine = new FileHelperEngine<Orders>();
var records = engine.ReadFile("Input.txt");
foreach (var record in records)
{
Console.WriteLine(record.CustomerID);
Console.WriteLine(record.OrderDate.ToString("dd/MM/yyyy"));
Console.WriteLine(record.Freight);
}
var engine=new FileHelperEngine();
var records=engine.ReadFile(“Input.txt”);
foreach(记录中的var记录)
{
Console.WriteLine(record.CustomerID);
Console.WriteLine(record.OrderDate.ToString(“dd/MM/yyyy”);
控制台。写入线(记录。运费);
}
出现在#END#
和#START#
之间的任何文本会发生什么情况?应该忽略这些文本吗?@KenClement在#END#
和#START#
之间不应该有文本(新行除外)所以我认为可以忽略它。使用XML或JSON,并序列化到对象!我看不到您输出的行result@Sakura我不在那个部分输出它。从这里我获取sError
变量,然后在RichTextBox中设置文本,就像这样errorBox.text=sError;
根据他的规范每个解析的变量可能包含多行内容,因此我认为任何进一步的分行都超出了问题或答案的范围。@Sakura这正是我想要的。我必须将其填充到变量中。唯一的问题是它没有将分行符保存在程序中。输出看起来更像@Sakura我为您添加的@Sakura现在可以正确地将行分隔开,但是因为我使用了iLineCount
,并且每次它通过foreach循环时都递增,所以我的switch语句会将其分隔开。如何获取正则表达式的特定匹配值?Ex。如果我想获取正则表达式找到的第一个匹配项并将其分配给特定变量?@Sakura我需要将每个正则表达式匹配分配给不同的变量。因此,第一个匹配进入Variable1,第二个匹配进入Variable2,第三个匹配进入Variable3。这有意义吗?CSV文件可能是一个选项,也可能不是一个选项。有时必须处理的文件格式是外部定义的-由客户、教授、行业或政府定义评论标准等。OP没有具体说明他是否有权更改所描述的格式。我认为我们应该询问而不是假设。观点很好。我希望我的回答没有被误解为居高临下。不,你没有遇到这种情况。(反正不是对我)我希望我没有受到责备,因为这不是我的本意。我同意你的主要观点,即文件内容应该保持简单(如CSV文件),如果你有这个选择,并且没有理由相信这会造成困难。