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.

http://jsfiddle.net/5n5vk/2/

EDIT :

La bonne façon: http://jsfiddle.net/5n5vk/3/

31
demandé sur Cœur 2012-10-06 06:25:00

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');
}​
22
répondu Peter Kuhar 2012-10-06 02:52:33

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]); }
}
52
répondu Édouard Lopez 2017-12-24 10:48:13

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
18
répondu SnailCrusher 2016-06-01 08:54:11

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.

2
répondu Jason Sebring 2017-07-27 21:51:43

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
0
répondu stallingOne 2017-01-16 09:39:17