Regex 有人知道英国日期格式的reg表达式吗

Regex 有人知道英国日期格式的reg表达式吗,regex,Regex,您好,是否有人知道英国日期格式的reg ex,例如dd/mm/yyyy dd或mm可以是1个字符,例如2010年1月1日,但年份必须始终为4个字符 提前谢谢 ^\d{1,2}/\d{1,2}/\d{4}$ 将匹配2000年1月1日、1999年5月7日,但也将匹配99/77/8765 所以,如果你想做一些基本的合理性检查,你需要 ^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/\d{4}$ 这将仍然与9999年2月31日相匹配,因此如果您想要捕捉这些,它

您好,是否有人知道英国日期格式的reg ex,例如dd/mm/yyyy

dd或mm可以是1个字符,例如2010年1月1日,但年份必须始终为4个字符

提前谢谢

^\d{1,2}/\d{1,2}/\d{4}$
将匹配2000年1月1日、1999年5月7日,但也将匹配99/77/8765

所以,如果你想做一些基本的合理性检查,你需要

^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/\d{4}$
这将仍然与9999年2月31日相匹配,因此如果您想要捕捉这些,它将变得更加毛茸茸:

^(?:(?:[12][0-9]|0?[1-9])/0?2|(?:30|[12][0-9]|0?[1-9])/(?:0?[469]|11)|(?:3[01]|[12][0-9]|0?[1-9])/(?:0?[13578]|1[02]))/\d{4}$
但这仍然赶不上闰年。因此,修改:

将匹配

1/1/2001
31/5/2010
29/02/2000
29/2/2400
23/5/1671
01/1/9000
失败

31/2/2000
31/6/1800
12/12/90
29/2/2100
33/3/3333
总之,正则表达式可能能够匹配日期;验证它们不是它们的强项,但如果它们是您可以使用的全部,那么肯定是可能的。但看起来很可怕:)

匹配:

  • 2010年1月1日
  • 2010年1月1日

但也有无效日期,如2月31日

^\d{1,2}/\d{1,2}/\d{4}$


大括号中有最小和最大字符数
\d
表示字符串的数字、
^
开始和
$
结束。

正则表达式不是此作业的正确工具

很难(但可能)找到正则表达式来匹配有效日期。像确保二月闰年有29天这样的事情在正则表达式中是不容易做到的

相反,请检查您的语言库是否提供任何验证日期的函数

PHP有一个这样的函数,名为:


这不会验证日期,但您可以检查格式

我遇到了类似的要求。 下面是完整的正则表达式以及闰年验证。 格式:年月日

(3[01]|[12]\d | 0[1-9])/(0[13578]| 10 | 12/(?!0000)d{4})(30 |[12]\d | 0[1-9])/(0[469]| 11/(?!0000){d{4}(2[0-8]|[01]\d{d{0[1-9]/(02)/(?!0000){d})| 29/(02)/(1600 | 2000 | 2400 | 2800 | 00)| 29/(02)/(\d\d)(0[48]|[2468][048]12479][26])

它可以很容易地修改为美国格式或其他欧盟格式

编辑:


(3[01[01[01[1[01[01[01[01[1[01[01[01[01[01[01[01[01[01[01[1[01[01[1[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[01[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[1[/(\d\d)(0[48]|[2468][048]|[13579][26])

在我看来,有两件事你想做,最好分开考虑

1) 您希望确保该日期是真实的日期。 例如,2019-02-29不是一个真实的日期,而2020-02-29是一个真实的日期,因为2020年是闰年

2) 您希望检查日期的格式是否正确(因此为dd/mm/yyyy)

第二点可以很容易地用一个简单的正则表达式来完成,有很多这样的例子

让事情复杂化的是,如果你问Firefox 2019-02-29是否是一个真实的日期,它会返回NaN,这是你所期望的

另一方面,Chrome会说这是一个真实的日期,并会在2019年3月1日返回给您,这将验证

Chrome,也会因为一些奇怪的原因接受一个数字作为一个合适的日期,输入“2”,它会给你从2001年回来的完整日期,这将验证

因此,第一步是创建一个函数,该函数尝试破译日期(无论格式如何),并跨浏览器返回一个布尔值,指示日期是否有效

function validatableDate(value) 
{
    Date.prototype.isValid = function() 
    {   // An invalid date object returns NaN for getTime() and NaN is the only
        // object not strictly equal to itself.
        return this.getTime() === this.getTime();
    };
    minTwoDigits = function(n) 
    {   //pads any digit less than 10 with a leading 0
        return (parseInt(n) < 10 ? '0' : '') + parseInt(n);
    }
    var valid_date = false;
    var iso_array = null;
    // check if there are date dividers (gets around chrome allowing single digit numbers)
    if ((value.indexOf('/') != -1) || (value.indexOf('-') != -1)) { //if we're dealing with - dividers we'll do some pre-processing and swap them out for /
        if (value.indexOf('-') != -1) {
            dash_parts = value.split('-');
            value = dash_parts.join("/");
            //if we have a leading year, we'll put it at the end and work things out from there
            if (dash_parts[0].length > 2) {
                value = dash_parts[1] + '/' + dash_parts[2] + '/' + dash_parts[0];
            }
        }

        parts = value.split('/');
        if (parts[0] > 12) { //convert to ISO from UK dd/mm/yyyy format
            iso_array = [parts[2], minTwoDigits(parts[1]), minTwoDigits(parts[0])]
        } else if (parts[1] > 12) { //convert to ISO from American mm/dd/yyyy format                                                
            iso_array = [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]
        } else //if a date is valid in either UK or US (e.g. 12/12/2017 , 10/10/2017) then we don't particularly care what format it is in - it's valid regardless
        {
            iso_array = [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]
        }

        if (Array.isArray(iso_array)) {
            value = iso_array.join("-");
            var d = new Date(value + 'T00:00:01Z');
            if (d.isValid()) //test if it is a valid date (there are issues with this in Chrome with Feb)
            {
                valid_date = true;
            }
            //if the month is Feb we need to do another step to cope with Chrome peculiarities
            if (parseInt(iso_array[1]) == 2) {
                month_info = new Date(iso_array[0], iso_array[1], 0);
                //if the day inputed is larger than the last day of the February in that year
                if (iso_array[2] > month_info.getDate()) {
                    valid_date = false;
                }
            }
        }
    }
    return valid_date;
}
然后你就知道日期是真实的,并且格式正确

对于yyyy-mm-dd格式,您需要执行以下操作:

function dateISO(value) {
    valid_iso_date=false;
    valid_date=validatableDate(value);
    if(valid_date && value.match(/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/))
    {   valid_iso_date=true;
    }
    return  valid_iso_date;             
}
这取决于你想做的有多彻底,当然,对于格式健全性的粗略检查来说,正则表达式就足够了。但是,如果您想测试日期是否为真实日期,以及格式是否有效,那么这将有助于指导您前进


感谢

@codaddict,正则表达式在很大程度上与语言无关。许多编程语言都有完美的函数来解析任何格式的日期,并处理一个月内的天数、闰年等。一旦找到可能的匹配项,通常最好将其填充到日期类型的变量中(在任何平台上),让平台担心闰年规则等。前0不是可选的,请在它后面加一个
,或者保持简单,或者在web上搜索一个表达式,该表达式可以处理包括闰年在内的所有内容。如果一个更复杂的表达式仍然不能处理所有的情况,那它就没有任何意义了。@Andrew Dunn:谢谢,我错过了这个,已经改正了。@Guffa:你说得对,而我——只是花了一段时间将monster regex更改为其确切的规格……我认为,如果不匹配二月和闰年,则匹配一个月内正确的天数是无用的;)除此之外,匹配表单和匹配值之间存在差异。2000年2月29日失败。1600年和2000年是闰年,但1700年、1800年和1900年并不是固定的-去掉29年之前的空间。我编辑了原稿。
bool checkdate  ( int $month  , int $day  , int $year)
\b(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d
function validatableDate(value) 
{
    Date.prototype.isValid = function() 
    {   // An invalid date object returns NaN for getTime() and NaN is the only
        // object not strictly equal to itself.
        return this.getTime() === this.getTime();
    };
    minTwoDigits = function(n) 
    {   //pads any digit less than 10 with a leading 0
        return (parseInt(n) < 10 ? '0' : '') + parseInt(n);
    }
    var valid_date = false;
    var iso_array = null;
    // check if there are date dividers (gets around chrome allowing single digit numbers)
    if ((value.indexOf('/') != -1) || (value.indexOf('-') != -1)) { //if we're dealing with - dividers we'll do some pre-processing and swap them out for /
        if (value.indexOf('-') != -1) {
            dash_parts = value.split('-');
            value = dash_parts.join("/");
            //if we have a leading year, we'll put it at the end and work things out from there
            if (dash_parts[0].length > 2) {
                value = dash_parts[1] + '/' + dash_parts[2] + '/' + dash_parts[0];
            }
        }

        parts = value.split('/');
        if (parts[0] > 12) { //convert to ISO from UK dd/mm/yyyy format
            iso_array = [parts[2], minTwoDigits(parts[1]), minTwoDigits(parts[0])]
        } else if (parts[1] > 12) { //convert to ISO from American mm/dd/yyyy format                                                
            iso_array = [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]
        } else //if a date is valid in either UK or US (e.g. 12/12/2017 , 10/10/2017) then we don't particularly care what format it is in - it's valid regardless
        {
            iso_array = [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]
        }

        if (Array.isArray(iso_array)) {
            value = iso_array.join("-");
            var d = new Date(value + 'T00:00:01Z');
            if (d.isValid()) //test if it is a valid date (there are issues with this in Chrome with Feb)
            {
                valid_date = true;
            }
            //if the month is Feb we need to do another step to cope with Chrome peculiarities
            if (parseInt(iso_array[1]) == 2) {
                month_info = new Date(iso_array[0], iso_array[1], 0);
                //if the day inputed is larger than the last day of the February in that year
                if (iso_array[2] > month_info.getDate()) {
                    valid_date = false;
                }
            }
        }
    }
    return valid_date;
}
function validatableDate(t) {
    Date.prototype.isValid = function () {
        return this.getTime() === this.getTime()
    }, minTwoDigits = function (t) {
        return (parseInt(t) < 10 ? "0" : "") + parseInt(t)
    };
    var a = !1,
        i = null;
    return -1 == t.indexOf("/") && -1 == t.indexOf("-") || (-1 != t.indexOf("-") && (dash_parts = t.split("-"), t = dash_parts.join("/"), dash_parts[0].length > 2 && (t = dash_parts[1] + "/" + dash_parts[2] + "/" + dash_parts[0])), parts = t.split("/"), i = parts[0] > 12 ? [parts[2], minTwoDigits(parts[1]), minTwoDigits(parts[0])] : (parts[1], [parts[2], minTwoDigits(parts[0]), minTwoDigits(parts[1])]), Array.isArray(i) && (t = i.join("-"), new Date(t + "T00:00:01Z").isValid() && (a = !0), 2 == parseInt(i[1]) && (month_info = new Date(i[0], i[1], 0), i[2] > month_info.getDate() && (a = !1)))), a
}
function dateUK(value) {
    valid_uk_date=false;
    valid_date=validatableDate(value);
    if(valid_date && value.match(/^(0?[1-9]|[12][0-9]|3[01])[\/](0?[1-9]|1[012])[\/]\d{4}$/))
    {   valid_uk_date=true;
    }
    return  valid_uk_date;              
}
function dateISO(value) {
    valid_iso_date=false;
    valid_date=validatableDate(value);
    if(valid_date && value.match(/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/))
    {   valid_iso_date=true;
    }
    return  valid_iso_date;             
}