我有一种情况需要从一般模式为[filename_]YYYYMMDD[.fileExtension]
的文件名中提取日期
e.g。 “xxx_20100326.xls”或 x2v_20100326.csv
以下程序完成工作
//Number of charecter in the substring is set to 8
//since the length of YYYYMMDD is 8
public static string ExtractDatesFromFileNames(string fileName)
{
return fileName.Substring(fileName.IndexOf("_") + 1, 8);
}
有没有更好的选择来实现同样的目标?
我基本上都在寻找标准练习。
我正在使用C#3.0和dotnet framework 3.5
编辑:
我喜欢LC的解决方案和方法。我使用过像
这样的程序string regExPattern = "^(?:.*_)?([0-9]{4})([0-9]{2})([0-9]{2})(?:\\..*)?$";
string result = Regex.Match(fileName, @regExPattern).Groups[1].Value;
该功能的输入是:“x2v_20100326.csv”
但输出为: 2010 而不是20100326
(这是预期的)。
任何人都可以帮忙。
答案 0 :(得分:2)
我会使用正则表达式,,特别是如果文件名中有多个下划线。然后,您可以捕获年,月,日,并在必要时返回DateTime
。这样你就可以确保你提取文件名的正确部分,它确实与你正在搜索的模式相匹配。
对于模式[filename_]YYYYMMDD[.fileExtension]
,我想的是:
^(?:.*_)?([0-9]{4})([0-9]{2})([0-9]{2})(?:\..*)?$
然后,按照该顺序,您捕获的群组将分别为年,月和日。
<强>解释强>
^
:字符串的开头。
(?:.*_)?
:一个可选的非捕获组,包含任意数量的字符,后跟下划线。
([0-9]{4})
:一个包含四位数的捕获组。
([0-9]{2})
:一个包含两位数的捕获组。
(?:\..*)?
:一个可选的非捕获组,包含一个点后跟任意数量的字符。
$
:字符串的结尾。
但是,我会补充一点,如果您确定您的文件名只有一个下划线,并且日期跟在下划线之后,那么您拥有的代码更清晰,可能会比正则表达式略快一些。根据预期的输入集,请记住这一点。
答案 1 :(得分:2)
只要您确定输入是标准格式,您拥有的代码就足够了。如果有可能它不会那么你应该为没有下划线的场景添加一些错误处理,或者天数/月没有用2位数字表示(这会弄乱8个字符的子串数),然后是DateTime.TryParse
以确保它是真实日期。
您的其他选择是:
SkipWhile
,Skip
,TakeWhile
方法忽略下划线并捕获数字,直到遇到句点。此查询最终看起来令人困惑,结果需要转换为字符串。{ '_', '.' }
并使用代表日期的数组元素。这些选项都不会产生比你现有的代码更清晰的代码,性能可能不会更好。
答案 2 :(得分:0)
你得到的代码很好,除非你遇到一个没有_的文件,你可能想检查IndexOf
的返回值,即。
int index = fileName.IndexOf("_");
if (index != -1)
return fileName.Substring(index + 1, 8);
else
...
如果您想检查它是否是有效日期,您可以拨打DateTime.TryParseExact