C# 控制台应用程序:捕获一些空格
C# Console Application: Catching Some Cases of White Spaces
我有一个解析 .txt 文件的 C# 控制台应用程序。 txt 文件每行有 4 个值。所以这里有几个示例:
c:\ecpg\myfolder\no_space.cfm 20160803 01:09:54 1574
c:\ecpg\myfolder\file with space.cfm 20160803 01:09:54 1574
c:\myfolder\.project 20170221 07:54:10 265
我正在使用以下内容根据每行中的白色 spaces 进行拆分:
while ((line = file.ReadLine()) != null)
{
string[] parts = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
}
问题是,在第 2 行的情况下,文件名中有一个 space,因此解析失败,因为现在我有 5 个值而不是 4 个。我该如何防止这种情况发生?也许有某种方法可以检测是否有 . (点)紧随 space?
谢谢!
改为按期间拆分。这将为您提供两个单独的字符串:文件和其余字符串。仅拆分 space 上的第二个字符串。第二个字符串拆分的第一个元素是您的文件扩展名:
while ((line = file.ReadLine()) != null)
{
string[] parts = line.Split('.');
string[] secondSplit = parts[1].Split(' ');
// put together the file path
string filePath = parts[0] + "." + secondSplit[0];
// Do something here with the rest of the second split: secondSplit
}
您可以使用 Regex 来 split
您的 string
,它会给您更好的输出。请检查我的代码:
while ((line = file.ReadLine()) != null)
{
string[] parts = Regex.Split(line, @"(\s+\s+)");
}
我也写在了DotNetFiddle你可以看看这个
编辑:我已经编辑了代码,它将涵盖您的所有场景。 New Solution Fiddle
while ((line = file.ReadLine()) != null)
{
string partOne = Regex.Match(line, @"[a-z](.*)[a-z]").Value;
//string[] parts = Regex.Split(line.Replace(partOne, ""), @"(\s+)");
string[] parts;
if (!string.IsNullOrEmpty(partOne))
{
parts = Regex.Split(line.Replace(partOne, ""), @"(\s+)");
}
else
{
parts = Regex.Split(line, @"(\s+)");
}
}
最终代码:
List<string> parts = new List<string>();
while ((line = file.ReadLine()) != null)
{
parts = new List<string>();
//string partOne = Regex.Match(line, @"[A-Za-z](.*)[A-Za-z]").Value;
//Update Regex for handle numeric value in part one.
string partOne = Regex.Match(line, @"[A-Za-z](.*)([A-Za-z]|([A-Za-z]{1}[0-9]))(.*?)\s").Value.Trim();
parts.Add(partOne);
string[] fianlParts;
if (!string.IsNullOrEmpty(partOne))
{
fianlParts = Regex.Split(line.Replace(partOne, ""), @"(\s+)");
}
else
{
fianlParts = Regex.Split(line, @"(\s+)");
}
foreach (string part in fianlParts)
{
if (!string.IsNullOrEmpty(part.Trim()))
{
parts.Add(part);
}
}
Console.WriteLine(parts[0] + " " + parts[1] + " " + parts[2] + " " + parts[3]);
}
此方法是手动的,但有效。它支持具有任意数量空格的文件名。
它的工作原理是从字符串的末尾定位空格,在循环中检索三个字段,最后检索文件名。如果您正在解析大文件,这里有足够的优化空间。
while ((line = file.ReadLine()) != null)
{
string[] parts = new string[4];
int n = -1;
for (int idx = 0; idx < 3; idx++)
{
n = line.LastIndexOf(' ');
parts[3-idx] = line.Substring(n + 1);
line = line.Substring(0, n).TrimEnd();
}
parts[0] = line; // filename
}
如果缺少一个或多个字段,您可以进行简单的模式检查。在您的文件中,第一个参数是文件名,第二个参数是 8 位日期,第三个是一天中的时间,第四个(可能)是文件大小。在这种情况下,这段代码应该更健壮(我没有尝试编译它,所以它可能包含拼写错误):
while ((line = file.ReadLine()) != null)
{
string[] parts = new string[4];
int n = -1;
for (int idx = 0; idx < 3; idx++)
{
n = line.LastIndexOf(' ');
if (n == -1 || n == 0) break;
string part = line.Substring(n + 1);
if (part.IndexOf(':') > 0) parts[2] = part;
else if (part.Length == 8) parts[1] = part;
else parts[3] = part; // assuming you don't have 8-digit filesizes
line = line.Substring(0, n).TrimEnd();
}
parts[0] = line.TrimEnd(); // filename
}
我有一个解析 .txt 文件的 C# 控制台应用程序。 txt 文件每行有 4 个值。所以这里有几个示例:
c:\ecpg\myfolder\no_space.cfm 20160803 01:09:54 1574
c:\ecpg\myfolder\file with space.cfm 20160803 01:09:54 1574
c:\myfolder\.project 20170221 07:54:10 265
我正在使用以下内容根据每行中的白色 spaces 进行拆分:
while ((line = file.ReadLine()) != null)
{
string[] parts = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
}
问题是,在第 2 行的情况下,文件名中有一个 space,因此解析失败,因为现在我有 5 个值而不是 4 个。我该如何防止这种情况发生?也许有某种方法可以检测是否有 . (点)紧随 space?
谢谢!
改为按期间拆分。这将为您提供两个单独的字符串:文件和其余字符串。仅拆分 space 上的第二个字符串。第二个字符串拆分的第一个元素是您的文件扩展名:
while ((line = file.ReadLine()) != null)
{
string[] parts = line.Split('.');
string[] secondSplit = parts[1].Split(' ');
// put together the file path
string filePath = parts[0] + "." + secondSplit[0];
// Do something here with the rest of the second split: secondSplit
}
您可以使用 Regex 来 split
您的 string
,它会给您更好的输出。请检查我的代码:
while ((line = file.ReadLine()) != null)
{
string[] parts = Regex.Split(line, @"(\s+\s+)");
}
我也写在了DotNetFiddle你可以看看这个
编辑:我已经编辑了代码,它将涵盖您的所有场景。 New Solution Fiddle
while ((line = file.ReadLine()) != null)
{
string partOne = Regex.Match(line, @"[a-z](.*)[a-z]").Value;
//string[] parts = Regex.Split(line.Replace(partOne, ""), @"(\s+)");
string[] parts;
if (!string.IsNullOrEmpty(partOne))
{
parts = Regex.Split(line.Replace(partOne, ""), @"(\s+)");
}
else
{
parts = Regex.Split(line, @"(\s+)");
}
}
最终代码:
List<string> parts = new List<string>();
while ((line = file.ReadLine()) != null)
{
parts = new List<string>();
//string partOne = Regex.Match(line, @"[A-Za-z](.*)[A-Za-z]").Value;
//Update Regex for handle numeric value in part one.
string partOne = Regex.Match(line, @"[A-Za-z](.*)([A-Za-z]|([A-Za-z]{1}[0-9]))(.*?)\s").Value.Trim();
parts.Add(partOne);
string[] fianlParts;
if (!string.IsNullOrEmpty(partOne))
{
fianlParts = Regex.Split(line.Replace(partOne, ""), @"(\s+)");
}
else
{
fianlParts = Regex.Split(line, @"(\s+)");
}
foreach (string part in fianlParts)
{
if (!string.IsNullOrEmpty(part.Trim()))
{
parts.Add(part);
}
}
Console.WriteLine(parts[0] + " " + parts[1] + " " + parts[2] + " " + parts[3]);
}
此方法是手动的,但有效。它支持具有任意数量空格的文件名。 它的工作原理是从字符串的末尾定位空格,在循环中检索三个字段,最后检索文件名。如果您正在解析大文件,这里有足够的优化空间。
while ((line = file.ReadLine()) != null)
{
string[] parts = new string[4];
int n = -1;
for (int idx = 0; idx < 3; idx++)
{
n = line.LastIndexOf(' ');
parts[3-idx] = line.Substring(n + 1);
line = line.Substring(0, n).TrimEnd();
}
parts[0] = line; // filename
}
如果缺少一个或多个字段,您可以进行简单的模式检查。在您的文件中,第一个参数是文件名,第二个参数是 8 位日期,第三个是一天中的时间,第四个(可能)是文件大小。在这种情况下,这段代码应该更健壮(我没有尝试编译它,所以它可能包含拼写错误):
while ((line = file.ReadLine()) != null)
{
string[] parts = new string[4];
int n = -1;
for (int idx = 0; idx < 3; idx++)
{
n = line.LastIndexOf(' ');
if (n == -1 || n == 0) break;
string part = line.Substring(n + 1);
if (part.IndexOf(':') > 0) parts[2] = part;
else if (part.Length == 8) parts[1] = part;
else parts[3] = part; // assuming you don't have 8-digit filesizes
line = line.Substring(0, n).TrimEnd();
}
parts[0] = line.TrimEnd(); // filename
}