Regex et ISO8601 formatted DateTime
j'ai formaté une chaîne DateTime ISO8601
2012-10-06T04:13:00+00:00
et le Regex suivant qui ne correspond pas à cette chaîne
#(d{4})-(d{2})-(d{2})T(d{2}):(d{2}):(d{2})+(d{2}):(d{2})#
Je n'arrive pas à comprendre pourquoi il ne correspond pas.
j'ai échappé à metacharacters, pour moi ça semble aller.
EDIT :
La bonne façon: http://jsfiddle.net/5n5vk/3/
5 réponses
ne citez pas le regex lorsque vous spécifiez un regex dans js. Un slash avant suffit.
alert($('#datepicker').val());
if($('#datepicker').val().match(
/(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})[+-](\d{2})\:(\d{2})/
)) {
alert('ok');
} else {
alert('not ok');
}
Incomplètes Regex
il est incomplet comme il corresponds invalid date2013-99-99T04:13:00+00:00
.
meilleure solution
le regex ci-dessous ne correspond pas à ce type de date invalide (cf. ISO 8601 Date de Validation Qui Ne suce pas). Vous pouvez tester avec le code suivant :
re = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?([0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/
var testDates = {
'date' : "2012-10-06T04:13:00+00:00",
'validDate' : "0785-10-10T04:13:00+00:00",
'invalidDate' : "2013-99-99T04:13:00+00:00",
'1234Date': '1234'
}
for (var d in testDates) {
if (re.test(testDates[d])) { console.info('[valid]: '+testDates[d]); }
else { console.error('[invalid]: '+testDates[d]); }
}
j'ai trouvé le RegExp qui essaie aussi de valider la date un peu exagérée pour moi. Je voulais juste savoir si une chaîne contient une chaîne de date ISO 8601. Je vérifierai si la date est valide après l'avoir convertie en Date objet.
voici 2 versions du RegExp. Ceci vérifie d'abord si la chaîne est une chaîne de date ISO 8601 valide. Les autres tests pour une chaîne de date complète incluant les heures / minutes / secondes (couramment utilisé dans les API)
/**
* RegExp to test a string for a ISO 8601 Date spec
* YYYY
* YYYY-MM
* YYYY-MM-DD
* YYYY-MM-DDThh:mmTZD
* YYYY-MM-DDThh:mm:ssTZD
* YYYY-MM-DDThh:mm:ss.sTZD
* @see: https://www.w3.org/TR/NOTE-datetime
* @type {RegExp}
*/
var ISO_8601 = /^\d{4}(-\d\d(-\d\d(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?)?)?$/i
/**
* RegExp to test a string for a full ISO 8601 Date
* Does not do any sort of date validation, only checks if the string is according to the ISO 8601 spec.
* YYYY-MM-DDThh:mm:ss
* YYYY-MM-DDThh:mm:ssTZD
* YYYY-MM-DDThh:mm:ss.sTZD
* @see: https://www.w3.org/TR/NOTE-datetime
* @type {RegExp}
*/
var ISO_8601_FULL = /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$/i
// Usage:
ISO_8601_FULL.test( "2016-05-24T15:54:14.876Z" ) // true
ISO_8601_FULL.test( "2002-12-31T23:00:00+01:00" ) // true
ISO_8601_FULL.test( "2016-02-01" ) // false
ISO_8601_FULL.test( "2016" ) // false
ISO_8601.test( "2016-02-01" ) // true
ISO_8601.test( "2016" ) // true
ISO_8601.test( "2002-12-31T23:00:00+01:00" ) // true
date JavaScript.toISOString () regex
ceci tente seulement de résoudre le motif de base de 2017-06-17T00:00:00.000Z
que vous attendez de Javascript de le faire.
const isoPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
une des choses les plus ennuyantes à propos de JSON est qu'on ne peut pas simplement passer une date et s'attendre à ce qu'elle se convertisse correctement. Puisque la plupart des gens utilisent JavaScript, c'est probablement pratique.
voici un extrait de démonstration si vous devez passer à mongo et avoir besoin de convertir.
if (isoPattern.test(json.startDate))
json.startDate = new Date(json.startDate);
je soutiens cette est une meilleure approche que vous pouvez être assuré que la date va parse, puis vous pouvez vérifier la portée désirée, tout étant assez simple et facile à maintenir que regex est grande, mais à un point.
pour ajouter à toutes ces bonnes réponses, j'ai trouvé que celui-ci fonctionne assez bien pour juste les dates ISO (PAS de temps)
(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))
v=passage x=ne-pas-pass)
2016-12-30 v
2016-13-31 x
2016-01-32 x
2016-02-29 v
2016-02-30 x
2017-02-29 v -> that's a false positive
1889-01-01 x -> you can add accepted centuries in the list: (?:18|19|20)
2099-01-01 v