在 C# 中写入文件时添加了额外的零
Extra zero's being added when writing to file in C#
我有一个包含某些记录的 csv 文件。这些记录中包含各种格式的日期。我想将所有格式转换为 MM/dd/yyyy,其中任何一位数字月份或日期前有一个 0。问题是,当它写入文件时,它添加了一堆额外的 0,我不知道为什么。我的数据示例是:
Title,Labels,Type,Current State,Created at,Accepted at,Deadline,Requested By,Description,Owned By,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment
pad,pad,epic,,9/26/2012 0:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655656 add security role xxxx,user updates,chore,accepted,7/20/2012 0:00,7/23/2012 0:00,,xxxx,"Call Number: 655656
Client Name: xxxxx
Department:
Address: xxxx
Phone: (xxx)xxx-xxxx
Open Date/Time: 6/25/2012 2:50:52 PM
Opened by: MAGIC
Problem Description: Effective Date: 07/09/2012 12:00 a
Area: CASE COMPASS.
Action: ADD ACCESS
Report/other Role: NONE
App Role: FIELD()
xxxx 7/18/2012 9:17 AM: created user id and assigned roles in enterprise security
Notes:
Problem Resolution: 7/19/12 - xxxx: Access granted, AD account added to the HL_Viewer security group.
CDS\xxxx -- S-1-5-21-508124448-3695470602-466989033-155771
Magic URL: http://magicweb02/magictsd
",Jane Doe, Please verify (Jane Doe - 07/23/2012 0:00),verified (Jamie Doe -07/23/2012 00:00),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655977 add security role xxxx,user updates,chore,accepted,7/19/2012 0:00,7/23/2012 0:00,,xxx,"Call Number: 655977
我的代码如下所示:
try
{
string file = File.ReadAllText("C:\\Users\hacknj\Desktop\mo_daily_activity_20160627_1412.csv");
// Define bad date
Regex badDate = new Regex(@"(\d{1,2}\/\d{1,2}\/\d{4})");
// Find Matches
MatchCollection matches = badDate.Matches(file);
// Go through each match
foreach (Match match in matches)
{
// get the match text
string matchText = match.Groups[0].ToString();
// Define DateTime
DateTime parsedDate;
DateTime.TryParse(matchText.Trim(), out parsedDate);
file = file.Replace(matchText, parsedDate.ToString("MM/dd/yyyy"));
}
File.WriteAllText("C:\\Users\hacknj\Desktop\TestFile.csv", file);
}
以下是日期写入文件后的一些情况:
pad,pad,epic,,000009/26/2012 0:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655656 add security role xxxx,user updates,chore,accepted,0000007/20/2012 0:00,00000007/23/2012 0:00,,xxxx,"Call Number: 655656
如果我在数据被替换之前查看数据,它看起来很好。我通过
做到这一点
MessageBox.Show("Match Text: " + matchText.Trim() + "\nParsed Date: " + parsedDate.ToString("MM/dd/yyyy"));
有人能告诉我我在做什么导致在写入文件时生成这些额外的 0 吗?
额外的零是循环中这一行 运行 的结果:
file = file.Replace(matchText, parsedDate.ToString("MM/dd/yyyy"));
如果同一日期在文件中出现多次,则每次您的正则表达式找到一个时,上面的行都会替换其中的 all。因此,如果日期需要一个前导零,则每次运行此行时,所有匹配的日期都会得到一个新的前导零。
相反,您可以使用 Regex.Replace()
和 MatchEvaluator
函数来重新格式化匹配的日期:
var newFile = Regex.Replace(file, @"(\d{1,2}\/\d{1,2}\/\d{4})", m =>
{
string matchText = m.Groups[0].ToString();
DateTime parsedDate;
if (DateTime.TryParse(matchText.Trim(), out parsedDate))
{
return parsedDate.ToString("MM/dd/yyyy");
}
else
{
return matchText;
}
});
File.WriteAllText("C:\\Users\hacknj\Desktop\TestFile.csv", newFile);
改变
Regex badDate = new Regex(@"(\d{1,2}\/\d{1,2}\/\d{4})");
至
Regex badDate = new Regex(@"\d{1,2}\/\d{1,2}\/\d{4}");
(去掉括号)。
改变
string matchText = match.Groups[0].ToString();
至
string matchText = match.Groups[0].Captures.ToString();
另外,如果你想捕获日、月、年。它会在紧要关头完成工作。无需在循环中进行替换(无论如何字符串都是不可变的,所以这是一个坏主意)。您不必担心 int.Parse 抛出异常,因为函数体将仅在内容与您定义的模式匹配时执行(2 位数字、2 位数字、2 或 4 位数字)
Regex badDate = new Regex(@"(?<Month>\d{1,2})\/(?<Day>\d{1,2})\/(?<Year>(20)?\d{2})");
File.WriteAllText(
path,
badDate.Replace(
file,
m => {
var year = int.Parse(m.Groups["Year"].Value);
var month = int.Parse(m.Groups["Month"].Value);
var day = int.Parse(m.Groups["Day"].Value);
if (year < 2000) year += 2000;
var datetime = new DateTime(year, month, day);
return datetime.ToString("MM/dd/yyyy");
}
)
);
(?<NamedGroup>RegexPattern)
语法使调试更容易一些,使用的代码更容易阅读。它仍然是正则表达式,但总比没有好。我更改了您的年份模式以选择性地接受 20 后跟恰好 2 位数字。这应该涵盖 2000 年到 2099 年之间的 2 或 4 位数年份。根据需要进行调整。对于迫在眉睫的 y2100 错误,我向您的祖先表示歉意。
我有一个包含某些记录的 csv 文件。这些记录中包含各种格式的日期。我想将所有格式转换为 MM/dd/yyyy,其中任何一位数字月份或日期前有一个 0。问题是,当它写入文件时,它添加了一堆额外的 0,我不知道为什么。我的数据示例是:
Title,Labels,Type,Current State,Created at,Accepted at,Deadline,Requested By,Description,Owned By,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment
pad,pad,epic,,9/26/2012 0:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655656 add security role xxxx,user updates,chore,accepted,7/20/2012 0:00,7/23/2012 0:00,,xxxx,"Call Number: 655656
Client Name: xxxxx
Department:
Address: xxxx
Phone: (xxx)xxx-xxxx
Open Date/Time: 6/25/2012 2:50:52 PM
Opened by: MAGIC
Problem Description: Effective Date: 07/09/2012 12:00 a
Area: CASE COMPASS.
Action: ADD ACCESS
Report/other Role: NONE
App Role: FIELD()
xxxx 7/18/2012 9:17 AM: created user id and assigned roles in enterprise security
Notes:
Problem Resolution: 7/19/12 - xxxx: Access granted, AD account added to the HL_Viewer security group.
CDS\xxxx -- S-1-5-21-508124448-3695470602-466989033-155771
Magic URL: http://magicweb02/magictsd
",Jane Doe, Please verify (Jane Doe - 07/23/2012 0:00),verified (Jamie Doe -07/23/2012 00:00),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655977 add security role xxxx,user updates,chore,accepted,7/19/2012 0:00,7/23/2012 0:00,,xxx,"Call Number: 655977
我的代码如下所示:
try
{
string file = File.ReadAllText("C:\\Users\hacknj\Desktop\mo_daily_activity_20160627_1412.csv");
// Define bad date
Regex badDate = new Regex(@"(\d{1,2}\/\d{1,2}\/\d{4})");
// Find Matches
MatchCollection matches = badDate.Matches(file);
// Go through each match
foreach (Match match in matches)
{
// get the match text
string matchText = match.Groups[0].ToString();
// Define DateTime
DateTime parsedDate;
DateTime.TryParse(matchText.Trim(), out parsedDate);
file = file.Replace(matchText, parsedDate.ToString("MM/dd/yyyy"));
}
File.WriteAllText("C:\\Users\hacknj\Desktop\TestFile.csv", file);
}
以下是日期写入文件后的一些情况:
pad,pad,epic,,000009/26/2012 0:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655656 add security role xxxx,user updates,chore,accepted,0000007/20/2012 0:00,00000007/23/2012 0:00,,xxxx,"Call Number: 655656
如果我在数据被替换之前查看数据,它看起来很好。我通过
做到这一点MessageBox.Show("Match Text: " + matchText.Trim() + "\nParsed Date: " + parsedDate.ToString("MM/dd/yyyy"));
有人能告诉我我在做什么导致在写入文件时生成这些额外的 0 吗?
额外的零是循环中这一行 运行 的结果:
file = file.Replace(matchText, parsedDate.ToString("MM/dd/yyyy"));
如果同一日期在文件中出现多次,则每次您的正则表达式找到一个时,上面的行都会替换其中的 all。因此,如果日期需要一个前导零,则每次运行此行时,所有匹配的日期都会得到一个新的前导零。
相反,您可以使用 Regex.Replace()
和 MatchEvaluator
函数来重新格式化匹配的日期:
var newFile = Regex.Replace(file, @"(\d{1,2}\/\d{1,2}\/\d{4})", m =>
{
string matchText = m.Groups[0].ToString();
DateTime parsedDate;
if (DateTime.TryParse(matchText.Trim(), out parsedDate))
{
return parsedDate.ToString("MM/dd/yyyy");
}
else
{
return matchText;
}
});
File.WriteAllText("C:\\Users\hacknj\Desktop\TestFile.csv", newFile);
改变
Regex badDate = new Regex(@"(\d{1,2}\/\d{1,2}\/\d{4})");
至Regex badDate = new Regex(@"\d{1,2}\/\d{1,2}\/\d{4}");
(去掉括号)。
改变
string matchText = match.Groups[0].ToString();
至string matchText = match.Groups[0].Captures.ToString();
另外,如果你想捕获日、月、年。它会在紧要关头完成工作。无需在循环中进行替换(无论如何字符串都是不可变的,所以这是一个坏主意)。您不必担心 int.Parse 抛出异常,因为函数体将仅在内容与您定义的模式匹配时执行(2 位数字、2 位数字、2 或 4 位数字)
Regex badDate = new Regex(@"(?<Month>\d{1,2})\/(?<Day>\d{1,2})\/(?<Year>(20)?\d{2})");
File.WriteAllText(
path,
badDate.Replace(
file,
m => {
var year = int.Parse(m.Groups["Year"].Value);
var month = int.Parse(m.Groups["Month"].Value);
var day = int.Parse(m.Groups["Day"].Value);
if (year < 2000) year += 2000;
var datetime = new DateTime(year, month, day);
return datetime.ToString("MM/dd/yyyy");
}
)
);
(?<NamedGroup>RegexPattern)
语法使调试更容易一些,使用的代码更容易阅读。它仍然是正则表达式,但总比没有好。我更改了您的年份模式以选择性地接受 20 后跟恰好 2 位数字。这应该涵盖 2000 年到 2099 年之间的 2 或 4 位数年份。根据需要进行调整。对于迫在眉睫的 y2100 错误,我向您的祖先表示歉意。