假设我有一个字符串,其中包含 YYYYmmDD 格式的日期,但位置可变,并且还包含其他数字序列
例如:
xx12x20240113yyyy123zzzz
20240201xxxx34yyy
xxxxxx202400315yyy1224zzz
是否有一种简单的方法来查找和提取数字的日期序列,或者我应该尝试通过循环读取所有序列并逐一测试它们?
目前,我正在使用循环,但我想找到一种更优雅的方式。
我建议使用正则表达式来获取原始匹配,我们使用
DateTime.TryParseExact
: 进行验证
有
string text =
@"xx12x20240113yyyy123zzzz
20240201xxxx34yyy
xxxxxx202400315yyy1224zzz";
我们可以放
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
...
var result = Regex
.Matches(text, "[0-9]{8}")
.Where(match => DateTime.TryParseExact(
match.Value,
"yyyyMMdd",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal,
out var date) &&
date.Year >= 1950 && date.Year <= 2050) // we don't want year 4000th and alike
.Select(match => match.Value);
Console.WriteLine(string.Join(Environment.NewLine, result));
输出:
20240113
20240201
如果您想要进行可靠的验证,8 位字符串实际上代表真实的日期值
DateTime.TryParseExact
可能是 .NET 中合适的工具。
如果您只想进行粗略验证以确保它是数字序列,那么正则表达式或
char.IsDigit
就足够了。
string [] lines =
{
"xx12x20240113yyyy123zzzz",
"20240201xxxx34yyy",
"xxxxxx202400315yyy1224zzz",
"20100925"
};
foreach (var date in ExtractDates(lines))
Console.Write("{0:yyyy-MM-dd} ", date);
// 2024-01-13 2024-02-01 0240-03-15 2010-09-25
IEnumerable<DateTime> ExtractDates(IEnumerable<string> lines)
{
const string dp = "yyyyMMdd";
foreach (var line in lines)
{
for (var i = 0; i <= line.Length - dp.Length; i++)
{
if (char.IsDigit(line, i) && DateTime.TryParseExact(line.Substring(i, dp.Length), dp, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateMatch))
{
yield return dateMatch;
i += dp.Length;
}
}
}
}