0

我正在使用“MM/DD/YYYY”格式的日期正则表达式,例如

"^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$"

它工作正常,没问题....在这里我想限制之间的一年"1950""2050"如何做到这一点,谁能帮助我....

4

2 回答 2

6

所以答案取决于你想如何完成任务。

您当前的Regex搜索模式将匹配 20 世纪和 21 世纪格式“MM/DD/YYYY”的大多数日期。因此,一种方法是遍历结果匹配,此时将其表示为字符串值,并将每个字符串解析为DateTime. 然后你可以做一些范围验证检查。

(注意:我从您的原件中删除了开头^和结尾$以使我的示例正常工作)

string input = "This is one date 07/04/1776 and this is another 12/07/1941. Today is 08/10/2019.";
string pattern = "(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\\d\\d";

List<DateTime> list = new List<DateTime>();
foreach (Match match in Regex.Matches(input, pattern))
{
    Console.WriteLine(match.Value);
    DateTime result;
    if (DateTime.TryParse(match.Value, out result))
    {
        if (result.Year >= 1950 && result.Year <= 2050)
        {
            list.Add(result);
        }
    }
}

Console.WriteLine("Number of valid dates: {0}", list.Count);

此代码输出以下内容,注意 1776 不匹配,其他两个日期匹配,但仅将最后一个添加到列表中。

12/07/1941
08/10/2019
Number of valid dates: 1

虽然这种方法有一些缺点,例如第二次循环结果以尝试进行范围验证,但也有一些优点。

  • 框架中的内置DateTime方法更容易处理,而不是不断调整Regex搜索模式,因为您可以接受的范围会随着时间的推移而变化。
  • 通过之后的范围检查,您还可以简化Regex搜索模式以使其更具包容性,甚至可以获取所有日期。
  • 一个更简单的Regex搜索模式更容易维护,并且也明确了代码的意图。Regex解读含义可能会令人困惑和棘手,尤其是对于经验不足的编码人员。
  • 复杂Regex的搜索模式可能会引入细微的错误。确保您的代码周围有良好的单元测试。

当然,您的另一种方法是调整Regex搜索模式,这样您就不必事后解析和检查。在大多数情况下,这将是最佳选择。您的搜索模式不会返回任何超出范围的值,因此您不必在该点循环或进行任何额外的检查。只要记住那些单元测试!

正如@skywalker 在他的回答中指出的那样,这种模式应该适合你。

string pattern = "(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19[5-9][0-9]|20[0-4][0-9]|2050)";
于 2012-04-26T12:09:05.463 回答
2

可以使用 19[5-9][0-9]|20[0-4][0-9]|2050 找到 1950-2050 年(含)

于 2012-04-26T12:52:43.837 回答