2015-08-17 15 views
6

Potrzebuję wyrażenie regularne do sprawdzenia poprawności w okresie ISO 8601 duration format (z wyjątkiem części ułamkowych, których nie potrzebuję).Regex dla okresów ISO 8601

PnYnMnDTnHnMnS

PNW

Oto co mam:

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

Jedynym problemem jest to, że struny P i PT wolno z tym regex ponieważ wszystkie części są "zero lub jeden" ?.

  • nie musi być co najmniej jeden składnik (data i czas)
  • Jeśli jest T to nie musi być składnikiem czasowej (H, M lub S)
  • Jeśli jest T to nie może lub może nie mieć żadnych składników data (Y, M lub D)
  • przepełnienia może (np P72H jest głównie równoważne P3D)

wejścia Dopuszczalne:

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

Niedopuszczalne Wejścia:

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

tej chwili nieważne struny przechodzą walidację po stronie klienta, ale upadające na stronie serwera, ponieważ jest przekazywana do DateInteval ale chciałbym, by upaść na kliencie Strona, jeśli to możliwe. Jeśli wszyscy korzystali z Chrome 40+, mógłbym podać minlength='3' na elemencie wejściowym, ale niestety tak nie jest.

+0

Można ustawić długość min jako '^ (= {3} $?.) P (\ d + Y)? (\ D + M)? (\ D + W)? (\ D + D)? (T (\ d + H)? (\ D + M)? (\ D + S)?)? $ '. –

+0

@stribizhev Obejmowałoby to tylko niektóre przypadki, ponieważ 'P4DT' można jeszcze wprowadzić. Również jakikolwiek powód na dół? –

+0

@stribizhev Dwa oczywiste były już udostępnione 'P' i' PT'. Zmieniliśmy je, aby wyjaśnić, proszę dać mi znać, czy jest coś jeszcze, co mogę dodać. –

Odpowiedz

8

Jeśli masz prawie wszystkie elementy opcjonalne, ale chcesz, aby upewnić się, że jest coś jeszcze po P lub T, można skorzystać z przeglądowej aheads:

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

Wymagają one ciągiem cyfr, a następnie literą z określonego zestawu, aby pojawiła się zaraz po poprzednim wzorze.

Zobacz demo

UPDATE

Jeśli P może być "pusta", użyj

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

Zobacz another demo. Tutaj (?!$) sprawdza, czy ciąg znaków nie jest równy P, a po prawej muszą być inne symbole.

Albo, jak sugeruje @UlugbekUmirov, to enough to just use T(?=\d) (ponieważ wszystkie opcjonalne elementy zaczynają się od cyfry):

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

Proszę zostaw komentarz tutaj, jeśli nadal występują problemy. –

+0

Jest to bardzo blisko, ale mogą również występować przypadki, w których określony jest tylko składnik czasu (np. "PT3H"). –

+0

Proszę zobaczyć moją edycję. Widzę, że część 'P' może być pusta, ale ciąg nie może równać się' P'. –

Powiązane problemy