如何替换文本文件中以特定单词开头并以 C# 中的特殊字符结尾的字符串?
How to replace a string in a text file which starts with a specific word and ends with a special character in C#?
我正在开发一个应用程序,它通过读取和写入文本文件来管理生产过程。首先,它从文本文件中读取信息并将信息放入数据网格视图中,例如:
然后应该可以在更改单元格值时更新文本文件中的信息。
这是示例测试文件:
567,Eindhoven,IGT,21,Stripping_e=20/05/2020,Stripping_s=21/05/2020,Stripping_f=,Cleaning_e=23/05/2020,Cleaning_s=27/05/2020,Cleaning_f=28/05/2020,Paint_e=28/05/2020,Paint_s=28/05/2020,Paint_f=29/05/2020,Cabinet_e=29/05/2020,Cabinet_s=31/05/2020,Cabinet_f=,Table_e=,Table_s=,Table_f=05/06/2020,Stand_e=05/06/2020,Stand_s=08/06/2020,Stand_f=,Display_e=08/06/2020,Display_s=11/06/2020,Display_f=,UControls_e=15/06/2020,UControls_s=,UControls_f=,Test_e=19/06/2020,Test_s=,Test_f=20/06/2020,Prepack_e=21/06/2020,Prepack_s=22/06/2020,Prepack_f=,Endpack_e=27/06/2020,Endpack_s=28/06/2020,Endpack_f=,Release_e=30/06/2020,Release_s=,Release_f=,
我想做的基本上是用单元格中输入的新日期替换文件中存储的日期。例如,对于 Cleaning_e=23/05/2020,
我想检查字符串是否以 Cleaning_e=
开头并以 ,
结尾将其替换为 Cleaning_e=12/09/2020,
即在单元格中输入新日期。
我当前的代码是:
private void ExportToTextFile(int selectedDate)
{
string filename = dataGridView1.Rows[clickedRow].Cells[0].Value.ToString();
// TextWriter writer = new StreamWriter($"../../{filename}.txt");
var text = new StringBuilder();
foreach (string s in File.ReadAllLines($"../../{filename}.txt"))
{
/* if (clickedColumn == 3 && selectedDate == 0)
text.AppendLine(s.Replace("Stripping_e=", $"Stripping_e={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 3 && selectedDate == 1)
text.AppendLine(s.Replace("Stripping_s=", $"Stripping_s={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 3 && selectedDate == 2)
text.AppendLine(s.Replace("Stripping_f=", $"Stripping_f={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 3 && selectedDate == 3)
text.AppendLine(s.Replace("Stripping_d=", $"Stripping_d={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else */if (clickedColumn == 4 && selectedDate == 0)
{
text.AppendLine(s.Replace("Cleaning_e=", $"Cleaning_e={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
}/*
else if (clickedColumn == 4 && selectedDate == 1)
text.AppendLine(s.Replace("Cleaning_s=", $"Cleaning_s={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 4 && selectedDate == 2)
text.AppendLine(s.Replace("Cleaning_f=", $"Cleaning_f={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 4 && selectedDate == 3)
text.AppendLine(s.Replace("Cleaning_d=", $"Cleaning_d={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));*/
}
using (var file = new StreamWriter(File.Create($"../../{filename}.txt")))
{
file.Write(text.ToString());
}
}
在我做了 text.AppendLine(s.Replace("Cleaning_e=",$"Cleaning_e={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
之后,它写入了文件:Cleaning_e=12/09/202023/05/2020
。
如何确保在添加新日期之前删除输入的旧日期?
我尝试删除该字符串并写入已删除字符串的索引,但我无法使其工作。我也尝试过使用正则表达式,但没有成功。
提前致谢!
要用正则表达式替换它,您可以使用
var testText = "some other stuff Cleaning_e=12/43/4555, some more ";
var newValue = "78/65/0000";
var rx = new Regex(@"Cleaning_e=(\d\d/\d\d/\d\d\d\d)?");
var result = rx.Replace(testText, $"Cleaning_e={newValue}");
这将替换日期。请注意,这会替换 Cleaning_e 的每一次出现,并且要求日期格式恰好具有 2 2 和 4 位数字。如果位数不同,可以使用
var rx = new Regex(@"Cleaning_e=(\d+/\d+/\d+)?");
相反。
我宁愿建议将其解析为适当的结构并更改其中的值,而不是直接操作文本文件。
如果是我...我会首先通过打破命令中的所有字段来解析文件(使用 string.Split
):
private const string SomeStuff =
"567,Eindhoven,IGT,21,Stripping_e=20/05/2020,Stripping_s=21/05/2020,Stripping_f=,Cleaning_e=23/05/2020,Cleaning_s=27/05/2020,Cleaning_f=28/05/2020,Paint_e=28/05/2020,Paint_s=28/05/2020,Paint_f=29/05/2020,Cabinet_e=29/05/2020,Cabinet_s=31/05/2020,Cabinet_f=,Table_e=,Table_s=,Table_f=05/06/2020,Stand_e=05/06/2020,Stand_s=08/06/2020,Stand_f=,Display_e=08/06/2020,Display_s=11/06/2020,Display_f=,UControls_e=15/06/2020,UControls_s=,UControls_f=,Test_e=19/06/2020,Test_s=,Test_f=20/06/2020,Prepack_e=21/06/2020,Prepack_s=22/06/2020,Prepack_f=,Endpack_e=27/06/2020,Endpack_s=28/06/2020,Endpack_f=,Release_e=30/06/2020,Release_s=,Release_f=,";
var fields = SomeStuff.Split(new[]{','}, StringSplitOptions.None);
到那时,您将拥有一组字符串。然后我会创建一个如下所示的正则表达式:
private const string ParsePattern = @"(?<key>[a-zA-Z0-9_]+)=(?<date>\d{2}/\d{2}/\d{4})";
private static readonly Regex ParseRegex = new Regex(ParsePattern);
该正则表达式会查找任意数量的字母、数字或下划线,然后是“=”,然后是两位数字、一个斜线、另外两位数字、另一个斜线,最后是另外四位数字。等号前的“组”将被命名为“key”,等号后的日期将被命名为“date”。
最后,我将构建一个没有日期的字段列表和一个字典来保存 field-name/date 组合:
var noDateStrings = new List<string>();
var dateDictionary = new Dictionary<string, DateTime>();
在 had 中,我将遍历已解析的字符串集合。如果与正则表达式匹配,我会把这两个组件放入字典中。如果没有匹配项,那么我会将它们粘贴到我的不匹配项中 List<string>
:
foreach (var field in fields)
{
var patternMatches = ParseRegex.Matches(field);
if (patternMatches.Count == 0)
{
noDateStrings.Add(field);
}
else
{
var groups = patternMatches[0].Groups;
var date = DateTime.ParseExact(groups["date"].ToString(), "dd/mm/yyyy",
CultureInfo.InvariantCulture);
dateDictionary.Add(groups["key"].ToString(), date);
}
}
这里有您需要的所有信息,可以为所欲为。
最后一件事要注意。我几乎总是主张在解析事物时使用 TryParse
而不是 Parse
。但是,在这种情况下,我知道该字符串与日期模式相匹配。除非该字符串表示非法日期(例如 32/13/2020),否则它将正常解析。
我正在开发一个应用程序,它通过读取和写入文本文件来管理生产过程。首先,它从文本文件中读取信息并将信息放入数据网格视图中,例如:
然后应该可以在更改单元格值时更新文本文件中的信息。
这是示例测试文件:
567,Eindhoven,IGT,21,Stripping_e=20/05/2020,Stripping_s=21/05/2020,Stripping_f=,Cleaning_e=23/05/2020,Cleaning_s=27/05/2020,Cleaning_f=28/05/2020,Paint_e=28/05/2020,Paint_s=28/05/2020,Paint_f=29/05/2020,Cabinet_e=29/05/2020,Cabinet_s=31/05/2020,Cabinet_f=,Table_e=,Table_s=,Table_f=05/06/2020,Stand_e=05/06/2020,Stand_s=08/06/2020,Stand_f=,Display_e=08/06/2020,Display_s=11/06/2020,Display_f=,UControls_e=15/06/2020,UControls_s=,UControls_f=,Test_e=19/06/2020,Test_s=,Test_f=20/06/2020,Prepack_e=21/06/2020,Prepack_s=22/06/2020,Prepack_f=,Endpack_e=27/06/2020,Endpack_s=28/06/2020,Endpack_f=,Release_e=30/06/2020,Release_s=,Release_f=,
我想做的基本上是用单元格中输入的新日期替换文件中存储的日期。例如,对于 Cleaning_e=23/05/2020,
我想检查字符串是否以 Cleaning_e=
开头并以 ,
结尾将其替换为 Cleaning_e=12/09/2020,
即在单元格中输入新日期。
我当前的代码是:
private void ExportToTextFile(int selectedDate)
{
string filename = dataGridView1.Rows[clickedRow].Cells[0].Value.ToString();
// TextWriter writer = new StreamWriter($"../../{filename}.txt");
var text = new StringBuilder();
foreach (string s in File.ReadAllLines($"../../{filename}.txt"))
{
/* if (clickedColumn == 3 && selectedDate == 0)
text.AppendLine(s.Replace("Stripping_e=", $"Stripping_e={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 3 && selectedDate == 1)
text.AppendLine(s.Replace("Stripping_s=", $"Stripping_s={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 3 && selectedDate == 2)
text.AppendLine(s.Replace("Stripping_f=", $"Stripping_f={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 3 && selectedDate == 3)
text.AppendLine(s.Replace("Stripping_d=", $"Stripping_d={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else */if (clickedColumn == 4 && selectedDate == 0)
{
text.AppendLine(s.Replace("Cleaning_e=", $"Cleaning_e={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
}/*
else if (clickedColumn == 4 && selectedDate == 1)
text.AppendLine(s.Replace("Cleaning_s=", $"Cleaning_s={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 4 && selectedDate == 2)
text.AppendLine(s.Replace("Cleaning_f=", $"Cleaning_f={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
else if (clickedColumn == 4 && selectedDate == 3)
text.AppendLine(s.Replace("Cleaning_d=", $"Cleaning_d={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));*/
}
using (var file = new StreamWriter(File.Create($"../../{filename}.txt")))
{
file.Write(text.ToString());
}
}
在我做了 text.AppendLine(s.Replace("Cleaning_e=",$"Cleaning_e={dataGridView1.Rows[clickedRow].Cells[clickedColumn].Value.ToString()}"));
之后,它写入了文件:Cleaning_e=12/09/202023/05/2020
。
如何确保在添加新日期之前删除输入的旧日期?
我尝试删除该字符串并写入已删除字符串的索引,但我无法使其工作。我也尝试过使用正则表达式,但没有成功。
提前致谢!
要用正则表达式替换它,您可以使用
var testText = "some other stuff Cleaning_e=12/43/4555, some more ";
var newValue = "78/65/0000";
var rx = new Regex(@"Cleaning_e=(\d\d/\d\d/\d\d\d\d)?");
var result = rx.Replace(testText, $"Cleaning_e={newValue}");
这将替换日期。请注意,这会替换 Cleaning_e 的每一次出现,并且要求日期格式恰好具有 2 2 和 4 位数字。如果位数不同,可以使用
var rx = new Regex(@"Cleaning_e=(\d+/\d+/\d+)?");
相反。
我宁愿建议将其解析为适当的结构并更改其中的值,而不是直接操作文本文件。
如果是我...我会首先通过打破命令中的所有字段来解析文件(使用 string.Split
):
private const string SomeStuff =
"567,Eindhoven,IGT,21,Stripping_e=20/05/2020,Stripping_s=21/05/2020,Stripping_f=,Cleaning_e=23/05/2020,Cleaning_s=27/05/2020,Cleaning_f=28/05/2020,Paint_e=28/05/2020,Paint_s=28/05/2020,Paint_f=29/05/2020,Cabinet_e=29/05/2020,Cabinet_s=31/05/2020,Cabinet_f=,Table_e=,Table_s=,Table_f=05/06/2020,Stand_e=05/06/2020,Stand_s=08/06/2020,Stand_f=,Display_e=08/06/2020,Display_s=11/06/2020,Display_f=,UControls_e=15/06/2020,UControls_s=,UControls_f=,Test_e=19/06/2020,Test_s=,Test_f=20/06/2020,Prepack_e=21/06/2020,Prepack_s=22/06/2020,Prepack_f=,Endpack_e=27/06/2020,Endpack_s=28/06/2020,Endpack_f=,Release_e=30/06/2020,Release_s=,Release_f=,";
var fields = SomeStuff.Split(new[]{','}, StringSplitOptions.None);
到那时,您将拥有一组字符串。然后我会创建一个如下所示的正则表达式:
private const string ParsePattern = @"(?<key>[a-zA-Z0-9_]+)=(?<date>\d{2}/\d{2}/\d{4})";
private static readonly Regex ParseRegex = new Regex(ParsePattern);
该正则表达式会查找任意数量的字母、数字或下划线,然后是“=”,然后是两位数字、一个斜线、另外两位数字、另一个斜线,最后是另外四位数字。等号前的“组”将被命名为“key”,等号后的日期将被命名为“date”。
最后,我将构建一个没有日期的字段列表和一个字典来保存 field-name/date 组合:
var noDateStrings = new List<string>();
var dateDictionary = new Dictionary<string, DateTime>();
在 had 中,我将遍历已解析的字符串集合。如果与正则表达式匹配,我会把这两个组件放入字典中。如果没有匹配项,那么我会将它们粘贴到我的不匹配项中 List<string>
:
foreach (var field in fields)
{
var patternMatches = ParseRegex.Matches(field);
if (patternMatches.Count == 0)
{
noDateStrings.Add(field);
}
else
{
var groups = patternMatches[0].Groups;
var date = DateTime.ParseExact(groups["date"].ToString(), "dd/mm/yyyy",
CultureInfo.InvariantCulture);
dateDictionary.Add(groups["key"].ToString(), date);
}
}
这里有您需要的所有信息,可以为所欲为。
最后一件事要注意。我几乎总是主张在解析事物时使用 TryParse
而不是 Parse
。但是,在这种情况下,我知道该字符串与日期模式相匹配。除非该字符串表示非法日期(例如 32/13/2020),否则它将正常解析。