在正则表达式模式中使用字符串[]



这是我第一次使用正则表达式。我需要有一个字符串数组作为一个正则表达式模式的一部分。具体来说,我试图匹配一个日期,所以我处理的两种格式是DDTTTTMMMMMMDDTTTT,月份是一个三个字母的缩写(例如:DEC),我无法控制月份在输入中的位置。

今天的日期示例是011150DECDEC011150

String[] months = {“JAN”, “FEB”, …, “DEC”}
String pattern1 = [0-9][0-9][0-9][0-9][0-9][0-9][months]; 
String pattern2 = [months][0-9][0-9][0-9][0-9][0-9][0-9];

例如,使用简单字符串连接:

string[] months = {"JAN", "FEB", "DEC"};
string monthsGroup = "(?:" + String.Join("|", months) + ")";
string pattern1 = @"d{6}" + monthsGroup;
string pattern2 = monthsGroup + @"d{6}";
Console.WriteLine(pattern1);    // d{6}(?:JAN|FEB|DEC)
Console.WriteLine(pattern2);    // (?:JAN|FEB|DEC)d{6}

当然,您也可以根据自己的喜好选择使用String.Format或插入字符串。

正则表达式不是解析日期的好方法;想象一下闰年问题。你可以使用DateTime。TryParseExact而不是

private static bool TryMyParse(string text, out DateTime result) => 
DateTime.TryParseExact(
text,
new string[] { "ddHHmmMMM", "MMMddHHmm"},
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal,
out result);

演示:

string[] tests = new string[] {
"011150DEC",
"DEC011150",
"abracadabra",
};
var report = string.Join(Environment.NewLine, tests
.Select(test => $"{test,20} => {(TryMyParse(test, out var date) ? date.ToString("dd MMMM yyyy HH:mm") : "???")}"));
Console.Write(result);

输出:

011150DEC => 01 December 2022 11:50
DEC011150 => 01 December 2022 11:50
abracadabra => ???

如果你坚持使用正则表达式,让我们一步一步地构建pattern:

// Let's use correct abbreviations instead of hardcoded ones
string months = string.Join("|", CultureInfo
.InvariantCulture
.DateTimeFormat
.AbbreviatedMonthNames
.Where(m => !string.IsNullOrEmpty(m)))
.ToUpper();
// Subpatterns for days, hours, minutes and months
string dd = "(?<dd>[0-3][0-9])"; // 00 and 39 day are still possible...
string HH = "(?<HH>[0-2][0-9])"; // 27 hour is still possible...
string mm = "(?<mm>[0-5][0-9])";
string MMM = $"(?<MMM>{months})";
// Time to construct the final pattern which should match 
// either ddHHmmMMM or MMMddHHmm:
string pattern = string.Join("|",
$"(^{dd}{HH}{mm}{MMM}$)",
$"(^{MMM}{dd}{HH}{mm}$)");

看看这个怪物(然而,它让天为00,39允许小时为26):

Console.Write(pattern);

输出:

(^(?<dd>[0-3][0-9])(?<HH>[0-2][0-9])(?<mm>[0-5][0-9])(?<MMM>JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)$)|(^(?<MMM>JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?<dd>[0-3][0-9])(?<HH>[0-2][0-9])(?<mm>[0-5][0-9])$)

最新更新