2015-08-17 3 views
6

Ich brauche einen regulären Ausdruck, um Dauern in der ISO 8601 duration format (mit Ausnahme der Bruchteile, die ich nicht brauche) zu validieren.Regex für ISO 8601 Dauern

PnYnMnDTnHnMnS

PNW

Hier ist, was ich habe:

^P(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$ 

Das einzige Problem ist, dass die Saiten P und PT mit dieser Regex als alle die erlaubt sind Teile sind "Null oder Eins" ?.

  • Es muss mindestens eine Komponente (Datum oder Zeit)
  • werden, wenn ein T dann gibt es eine Zeitkomponente (H, M oder S)
  • werden muss, wenn es ein ist T dann kann es keine oder Datum Komponenten sein kann (Y, M, oder D)
  • Überlauf erlaubt ist (zB P72H ist meist entspricht P3D)

Acceptable Eingänge:

P1Y  // date component only 
P2MT30M // date and time components 
PT6H  // time component only 
P5W  // another date component 

Unzulässige Eingänge:

P   // no components 
PT  // no components 
P3MT  // T specified but not time components 

Gerade jetzt die ungültigen Strings sind vorbei clientseitige Validierung aber Fehler auf der Server-Seite, weil es in DateInteval übergeben wird, aber ich möchte auf dem Client zum Scheitern verurteilt Seite wenn möglich. Wenn jeder Chrome 40+ verwenden würde, könnte ich minlength='3' auf dem Eingabeelement angeben, aber das ist leider nicht der Fall.

+0

Sie die Mindestlänge einstellen können als '^ (= {3,} $?.) P (\ d + Y)? (\ D + M)? (\ D + W)? (\ D + D)? (T (\ d + H)? (\ D + M)? (\ D + S)?)? $ '. –

+0

@stribizhev Das würde nur einige Fälle abdecken, da 'P4DT' noch eingegeben werden konnte. Auch ein Grund für den Downvote? –

+0

@stribizhev Die zwei offensichtlichen wurden bereits 'P' und' PT' geteilt. Ich habe bearbeitet, um zu klären, lass es mich wissen, wenn ich noch etwas hinzufügen kann. –

Antwort

8

Wenn Sie fast alle Teile optional, aber Sie wollen sicherstellen, dass es etwas anderes nach P oder T ist, können Sie die Verwendung von Look-aheads machen: gefolgt

^P(?=\d+[YMWD])(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d+[HMS])(\d+H)?(\d+M)?(\d+S)?)?$ 
    ^^^^^^^^^^^^        ^^^^^^^^^^^^ 

Sie erfordern eine Folge von Ziffern um einen Buchstaben aus der angegebenen Menge, um direkt nach dem vorhergehenden Muster zu erscheinen.

Siehe demo

UPDATE

Wenn P kann "leer" sein, verwenden

^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d+[HMS])(\d+H)?(\d+M)?(\d+S)?)?$ 

another demo See. Hier stellt (?!$) sicher, dass die Zeichenkette ungleich P ist, und es müssen einige andere Symbole auf der rechten Seite sein.

Oder, wie @UlugbekUmirov schon sagt, es ist enough to just use T(?=\d) (da alle optionalen Teile mit einer Ziffer beginnen):

^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$ 
+0

Bitte geben Sie hier einen Kommentar ein, wenn es noch Probleme gibt. –

+0

Dies ist sehr nahe, aber es kann auch Fälle geben, in denen nur eine Zeitkomponente spezifiziert ist (z.B. 'PT3H'). –

+0

Bitte sehen Sie meine Bearbeitung. Ich sehe, dass 'P' Teil kann leer sein, aber die Zeichenfolge kann nicht gleich" P ". –