【问题标题】:RegEx String Validator正则表达式字符串验证器
【发布时间】:2011-12-21 09:48:47
【问题描述】:

在我的 MVC3 应用程序中,在其中一个实体上,我将出生日期保存为字符串。为什么 ?因为我的应用程序允许存储早已死去的人的出生日期,例如。苏格拉底、柏拉图、伊壁鸠鲁……等等,据我所知 DateTime 类不允许这样做。

现在显然我们不知道伊壁鸠鲁的确切出生日期,例如,我们只知道出生年份 [公元前 341 年],所以我正在考虑构建一个自定义验证器,它将验证输入出生日期的字符串,并确保它们都符合以下格式:

12 Feb 1809
Feb 1809
341
341 BCE
Oct 341 BCE
11 Mar 5 BCE

我需要编写一个正则表达式来匹配上述任何一个,当然不匹配其他任何内容。

更新

非常感谢你,我希望我在构建 RegExes 方面和你一样好!由于我的应用程序使用 ASP.net MVC3,因此我想坚持使用 .NET RegEx 类(为方便起见)。

luastoned 的答案似乎有效;我似乎无法用我扔给它的所有测试数据来打破它的逻辑。

但有一件事,我也可以允许 BC 吗?因为有些人使用 BC 而其他人使用 BCE

更新 2

M42 的正则表达式似乎工作得更好。我刚刚复制了它并在我的自定义验证器中使用了它(下面的 PasteBin 链接中的代码)。

【问题讨论】:

    标签: regex asp.net-mvc-3 validation


    【解决方案1】:

    怎么样:

    /^(?:\d+\s)?(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)?(?:\s?\d+)(?:\sBCE)?$/
    

    这是一个带有测试用例的 perl 脚本:

    #!/usr/local/bin/perl 
    use strict;
    use warnings;
    use Test::More;
    
    my $re1 = qr/^(?:\d+\s)?(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)?(?:\s?\d+)(?:\sBCE)?$/;
    while(<DATA>) {
        chomp;
        if (/$re1/) {
            ok(1, "input = $_");
        } else {
            ok(0, "input = $_");
        }
    }
    done_testing;
    
    __DATA__
    12 Feb 1809
    Feb 1809
    341
    341 BCE
    Oct 341 BCE
    11 Mar 5 BCE
    12D09
    1s909
    A3 43 4 BCE
    a 1
    3F9
    
    abc
    BCE
    123b456
    

    输出:

    # Looks like you failed 9 tests of 15.
    ok 1 - input = 12 Feb 1809
    ok 2 - input = Feb 1809
    ok 3 - input = 341
    ok 4 - input = 341 BCE
    ok 5 - input = Oct 341 BCE
    ok 6 - input = 11 Mar 5 BCE
    not ok 7 - input = 12D09
    not ok 8 - input = 1s909
    not ok 9 - input = A3 43 4 BCE
    not ok 10 - input = a 1
    not ok 11 - input = 3F9
    not ok 12 - input = 
    not ok 13 - input = abc
    not ok 14 - input = BCE
    not ok 15 - input = 123b456
    

    【讨论】:

      【解决方案2】:

      这看起来像是我做过的最奇怪的正则表达式:

      (\d+\s?)?(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)?\s(\d+\s)?(BCE)?

      我不知道会有多少误报..

      您可以在Regexr上查看示例

      【讨论】:

      • 为什么是(BCE|\d{4})?(BCE)? 应该足够了,因为 BCE 是最后一个(OP 中的年份示例分别是 180918093413413415,最后三个分别是 BCE。 )
      • 这匹配:" " - 一个包含单个空格的字符串。表达式还应该有 ^$ 锚点。
      • 不仅如此,而且在我的代码中,它还允许诸如 [ 12 December 341 BCE ] 这样的字符串通过! :( 这是我的 C# 的 PasteBin link。任何帮助都会很棒。
      【解决方案3】:

      不是 RegExr 的朋友(也不知道 MVC3 中正则表达式的局限性),请允许我介绍一个带有命名捕获的 PHP 版本 (demo):

      (?:(?:(?P<date>\d{1,2})\s)?(?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))?(?:(?:^|\s)(?P<year>\d+))?(?:\s(?P<bce>BCE))?
      

      这是基于@luastoned 的answer

      【讨论】:

        猜你喜欢
        • 2018-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-04
        • 2016-07-30
        相关资源
        最近更新 更多