If you have worked through the Tutorial, you actually know the essential parts of the sample building. Now we try to build some patterns together, so that the whole thing loses its fright.
Of course you have to find out which rules the input should follow. A house number, a license plate, a book ID or the membership number in your gymnastics club have (in the best case) a certain logic. You have to recognize this logic first to be able to create your pattern correctly. A source could be for example Wikipedia, or the pages of the KFZ-Zulassungsbehörde or or or or... The best thing, of course, is if your client can clearly define his rules. (I have heard that there should be such a thing!).
A website operator wants an input field for a German mobile phone number prefix on his page.
All German network codes for mobile communications have in common that they consist of the national traffic prefix 0, the network code 15/16/17 and the one- to two-digit block code. (For the network identifier 15, the block identifier has two digits, otherwise it has one.) 0151n, 0152n, 0157n, 0159n, 0160, 0162, 0163, 017n (Wikipedia Example! No claim to correctness!)
building instruction
As such the similarities. '01' immediately catches the eye. 0151n, 0152n, 0157n, 0159n, 0160, 0162, 0163, 017n. We can already make a note of this. pattern = "01"
The next digit is a 5, a 6 or a 7, so we take the pipe |for the alternatives and put it in parentheses. pattern = "01(5|6|7)"
After a 5 follows a 1, 2, 7 or 9, here we can use the square selection bracket..5[1279]...
Arbitrary digit follows You best use the short form \d ..5[1279]\d.. = pattern="01(5[1279]\d|6[023]|7)
And the second option: After a 6 follows a digit 0, 2 or 3. Here we also use the selection bracket...6[023]...
And the third option: After a 7 follows any digit 0 to 9. We could also use the predefined character for this. ..7\d..
Now you put the whole thing together pattern="01(5[1279]\d|6[023]|7\d)
Another detailed test with many correct and incorrect entries - I think that's how it fits.
Test
D - mobile area code: Format: 015xx or 0162 oder 017x pattern="01(5[1279]\d|6[023]|7\d)
Your bookseller (yes, that's the one with the printed paper - you've probably seen one of the big shopping stamps before...) would like to have the International Standard Book Number ISBN as a supplement on his order page. You'll find the number on the back of every paperback or on the cover of bound books. So that it is not too easy there are 2 ISBN types.
The ISBN-10 - who would have thought that - always has 10 digits, and consists of four partsn. The group number, the publisher number, the title number and the check digit. The first three groups can contain different numbers of digits (1 to 7), the check digit is a one-digit number. Example: ISBN 386-6801-92-9
The second variant the ISBN-13, well, consists of a total of 13 digits, it has a prefix: "978" or "979". Example: ISBN 978-3-86680-192-9
The rule states that the groups are to be formatted with hyphens "-".
building instruction
As the ISBN13 prefix is built fast: 97 + an 8 or 9 pattern="97[89]". Since it is optional, we put it in brackets with a question mark (once or not) pattern="(97[89]-)?
If we didn't have to insert these hyphens with this rule (1 to 7 digits), the rest wouldn't be done quickly. without prefix or | with prefix, finished.pattern="\d{10}|97[89]\d{10}"
But the rule is more complicated. The ISBN consists of 3 blocks, which can have between 1 and 7 digits \d{1,7} and separated by hyphens - and then a check digit \d{1,7}-\d{1,7}-\d{1,7}-\d. Or briefly (\d{1,7}-){3}\d
The ISBN must consist of a total of 13 characters (10 digits + 3 hyphens) except for the prefix. As we have the pattern right now, it can be between 4 and 22 characters without a prefix, which is of course not optimal. The ISBN is a nice example of how to apply Predictions(?=...).
We predict that the input will only be correct if it consists of 13 characters. pattern="(?=.{13}$)(\d{1,7}-){3}\d"
Since each block must occur at least once, a single block cannot be longer than 7, so the rule is fulfilled even if we tighten the pattern a little bit. + stands for 1 time or more, we take this: pattern="(?=.{13}$)(\d+-){3}\d"
The optional prefix attached at the front: pattern="(97[89]-)?(?=.{13}$)(\d+-){3}\d". Wonderful!
Although it actually violates the rule, we also build a varante without separators, because the hyphen is annoying during input, which may have to be corrected for display e.g. with Javascript or on the server, just as the check digit should be subjected to a test. \d{10}|97[89]\d{10} we build our pattern with the pipe | at the front. ==> pattern="\d{10}|97[89]\d{10}|(97[89]-)?(?=.{13}$)(\d+-){3}\d
This part \d{10}|97[89]\d{10} you could also shorten (97[89])?\d{10}. ==>pattern="(97[89])?\d{10}|(97[89]-)?(?=.{13}$)(\d+-){3}\d
Test
ISBN-10 ISBN-13 Format: (978-)12-345-6789-0 oder (978)1234567890 <input type="text" pattern="(97[89])?\d{10}|(97[89]-)?(?=.{13}$)(\d+-){3}\d">
The form should have an input field for the date. The date should be completely validated by the browser. And it should take leap years into account. Since the year 1584 every 4 years a day (the 29.February) is inserted, but not in years which are divisible by 100. By 400 divisible years but then nevertheless.Pooh..., then go on.
As format we take this time the German format, thus: TT.MM.YYYY. Further date formats of this world (MM-DD-YY, YY/MM/DD ...) can be found in the examples or in the database. I think there are many solutions, one possible solution (the best) is this:
building instruction
28days: All months of the year have at least 01 to 28 days. Since this is not so easy to sample, we divide it logically. 01 - 09 0[1-9]or 10 - 19 1\dor 20 - 28 2[0-8] We will assemble it with 'or'. The days:|. (0[1-9]|1\d|2[0-8]).
The months with at least 28 days, i.e. all: The months (0[1-9]|1[012]).
Together, between day and month a masked dot ( )\.( ): (0[1-9]|1\d|2[0-8])\.(0[1-9]|1[012]).
30 days All months except February have a 29th and 30th day. The days (29|30)
Months 1 to 12 without 2 (0[13-9]|1[0-2])
Assembled: (29|30)\.(0[13-9]|1[0-2])
Assembled: Correct is the first or the second or the third block: (28days.MM | 30days.MM | 31days.MM) (0[1-9]|1\d|2[0-8])\.(0[1-9]|1[012])|(29|30)\.(0[13-9]|1[0-2])|(31\.(0[13578]|1[02]))
And the years equal \.\d{4} Exclude the year 0 that did not exist equal with negative prediction (?!.*0000) ((0[1-9]|1\d|2[0-8])\.(0[1-9]|1[012])|(29|30)\.(0[13-9]|1[0-2])|(31\.(0[13578]|1[02])))\.(?!.*0000)\d{4}
The leap day 29 February 29 29\.02\. will be inserted every 4 years from the year 1584:
1584 - 1596 1584|1588]|1592|1596, shorter: 158[48]|159[26]
1600 - 1996 1[6-9]([02468][048]|[13579][26])
2000 - 9996 [2-9]\d([02468][048]|[13579][26])
write somewhat shorter: (158[48]|159[26])|1[6-9]([02468][048]|[13579][26])|[2-9]\d([02468][048]|[13579][26])
so, in these years there is thus the 29.February, but not in the years which are divisible by 100 smooth. (1700, 1800, 1900...). However, by 400 divisible years have a 29th February. I have now solved this simply in such a way that I have simply written down the 400 leap years 1600 - 9600 (16|[2468][048]|[3579][26])00 and we must exclude the calendar year '0', since it never existed. The negative prediction is also suitable for this. (?!.*0000)
Date Format: TT.MM.JJJJ (Years: ~1500-4000 with leap year test pattern="((0[1-9]|1\d|2[0-8])\.(0[1-9]|1[0-2])|(29|30)\.(0[13-9]|1[0-2])|31\.(0[13578]|1[02]))\.[1-4]\d{3}|(29\.02\.)(((1[5-9]|[2-4]\d)(0[48]|[13579][26]|[2468][048]))|(16|[24]0|2[048]|3[26])00)">
For an event calendar we need a registration form that accepts input data from a given date to a given date. This can certainly be solved with Javascript. But this is a tutorial about HTML5 form-input-pattern, and it works. As default this time I chose the American date format YYYY-MM-DD. The date range is: 2014-08-18 to 2015-06-16. You could set this default on the server before delivering the page.
building instruction
First, let's dismantle the months: In the year 2014 August 08 has only the days 18 to 31. Of course we have to split the days. That is the day can be 18 or 19 1[89], one of the twenties 2\d or 30 and 31 3[01]. So we have the first option, which we link to |. 08-(1[89]|2\d|3[01])
September and November 09|11 each have 30 days. Day one to nine 0[1-9], day 10 to 29[12]\d and day three 30 summarized thus (09|11)-(0[1-9]|[12]\d|30)
Months 10 and 12 10|12 or 1[02] have 31 days. 1[02]-0[1-9]|[12]\d|3[01]
For the year 2014 we have "2014-((Option1-14) or (Option2-14) or (Option3-14))".
2014-((08-(1[89]|2\d|3[01]))|((09|11)-(0[1-9]|[12]\d|30))|((10|12)-(0[1-9]|[12]\d|3[01])))
In 2015 the months 1, 3 and 5 01|03|05 each have 31 days (0[135])-(0[1-9]|[12]\d|3[01])
The month of February has only 28 days 02-(0[1-9]|1\d|2[1-8])
The month of April has 30 days 04-(0[1-9]|[12]\d|30)
And June has only the given 16 days 06-(0[1-9]|1[0-6])
Together: "(2015-( (Option1)|(Option2)|(Option3)|(Option4) )"
Now we also link the years with the Oder sign | and a few brackets (..) to this:
(2014-((Option1-14)|(Option2-14)|(Option3-14))) | (2015-((Option1-15)|(Option2-15)|(Option3-15)|(Option4-15)))
2015-((02-(0[1-9]|1\d|2[1-8]))|(04-(0[1-9]|[12]\d|30))|((01|03|05)-(0[1-9]|[12]\d|3[01]))|(06-(0[1-9]|1[0-6])))
Test
Date Format: 2014-08-18 bis 2015-06-16 <input type="text" pattern="201(4-((08-(1[89]|2\d|3[01]))|((09|11)-(0[1-9]|[12]\d|30))|((10|12)-(0[1-9]|[12]\d|3[01])))|(5-((02-(0[1-9]|1\d|2[0-8]))|(04-(0[1-9]|[12]\d|30))|((01|03|05)-(0[1-9]|[12]\d|3[01]))|(06-(0[1-9]|1[0-6])))))">
2014-09-28 2015-02-28 2015-06-16
2014-07-28 2015-02-29 2015.02.28 2014-1-216
Car license plate (Germany)
demand German plates
A form for an insurance bureau should contain a field for the vehicle indicator that checks the validity before it is sent. Only indicators from Germany are to be taken into account.
A German mark may have 1 to 3 letters as a distinguishing sign (city / district) and may not be shorter than 5 and longer than 8 characters (+ 1 space). Previously used hyphens are not accepted. There are no 3 identical letters in a row (A and AA but no AAA). Certain combinations of letters are forbidden and there are historical vehicles that may have a H at last place and the electric carts :) E. Special plates are not included in the sample. Many local authorities have their own rules, so this example can only be an example.
building instruction
An identifier can have 1 to 3 letters as a distinguishing sign (city / district). [A-Z]{1,3}
A space is followed by (- we no longer accept the previously used hyphen.) 1 to 2 letters[A-Z]{1,2} .. and 1 to 4 numbers. \d{1,4}
But now that a license plate may not be shorter than 5 and longer than 8 characters (+ 1 blank), we specify the total length with the predictive statement. (?=.{6,9}$)
Of course there are further restrictions. For example, there are A and AA as distinguishing signs but no AAA, so there are no 3 letters in a row. So we close 3 identical letters with the negative prediction (?!...and the reference to a parenthesis content/1aus:(?!(.)\1\1)
Now certain letter combinations are not allowed. We can also exclude these with the negative prediction. (?!HJ|KZ|NS|SA|SD|SS|R[A-Z]) Achja, there were still the historical vehicles that could have a H at the last place and the electric carts :) E , but the total length remains the same.
Test
Car license plate (Germany) Format: A BC1234 oder AB C1234 oder ABC D123 pattern="(?=.{6,9}$)(?!(.)\1\1)([A-Z]){1,3} (?!HJ|KZ|NS|SA|SD|SS|R[A-Z])[A-Z]{1,2}\d{1,4}[HE]?"
AA KA256 AA KA2356 S TR1245 STR A1245 E S1234 AA KA235H
AA-KA256 AAA KA256 STR AB1245 ST AB 12 ST KZ123 AA KA2356H
grades
demand
This exercise looks at the grading system that is common in Germany and some other countries. A grade is not just a number between 1 and 6. There are umpteen Schulnoten-Systeme. Let's see if we can build some patterns for it.
The German grading system has six levels. Depending on the federal state or type of school and some other criteria, whole grades, half grades, quarter grades or tenth grades with one or two decimal places are used. Sometimes there is also a grade of 1+ in the system, which can mean either 0.7 or 0.75. The sample creator should then know which of the options he wants to or must choose for his form.
building instruction whole grades
Now, a pattern for a whole note is of course the simplest case. We simply list all valid numbers in square brackets. We can name each character individually, or we can write the valid range. A mixture of both is also correct. You can write this either as a list of all numbers 123456 or as a range 1-6 or even a mixture of both [123-6]
Test
Format: n pattern="[1-6]" pattern="[123456]" pattern="[1-456]"
1 3 6
7 $ A
building instruction halbe Noten
Since the entire expression in square brackets [..] represents only one character, we must also set several square brackets [...][...] for several characters. We can simply interpose the comma. The pattern looks like this: [1-6],[05]. But hello. So the note 6,5 is valid. So we have to remove the 6 from the group and add it as an alternative with the 'or' character |.
The PC workers, who take a point instead of a comma, just have to replace it. But beware, the dot stands for any character, so you have to mask it with the backslash \! Of course we can also sample both alternatives for international pages, then we have to put it in square brackets again, because the whole expression in these brackets is place maker for only one character.
Test
Half notes: with commaFormat: n,0 n,5 pattern="[1-5],[05]|6,0"
1,0 2,5 5,0
1,0 A,4 6,5
Half notes: with dot Format: n.0 n.5 pattern="[12345]\.[05]|6\.0"
1.0 2.5 5.0
1.3 A.4 6.5
Half notes: with dot or commaFormat: n,0 n,5 n.0 n.5 pattern="[1-5][.,][05]|6[.,]0"
1.0 2,0 5.0
1,3 A.4 6.5
building instruction Halbe Noten (optional)
Half notes can have one digit after the comma, but don't have to. We simply take the patterns from above and give the decimal places the optional character ?. But since the comma must not be the last, we have to group it with round brackets (..). The comma zero after the 6 must also include round clones ([\.,]0)?, because one cannot stand without the other and the option then applies to both places.
Test
Half notes Format: n oder n,0 or n,5 pattern="[1-5]([.,][05])?|6([.,]0)?"
1 2,5 5.0
1,4 A.4 6.5
building instruction Viertel Noten
Good, the 6 is clear, there comes only one more decimal point zero. We can write that down like this. 6,00 If there is (for the upper stages) the 1+: also the 0,75|6,00. As further notes there are the numbers 1 to 5 0,75|6,00|[1-5] and the corresponding decimal places ,00 - ,25 - ,50 or ,75. For this we have to pack the decimal alternative into a group. (00|25|50|75)
Actually as above, only the decimal places have to be treated as options.
Test
Only one decimal place: pattern="0,7|6(,0)?|[1-5](,[0257])"
ein oder zwei optionale Nachkommastellen: pattern="0,7[05]?|[1-5](,(00?|2[05]?|50?|7[05]?))?|6(,00?)?"
0,7 3,2 4,75
0,8 4,325 7,2
building instruction quarter notes (optional with +/-)
Just for fun: You could also write the notes with a plus or minus sign in this way. The hyphen - does not have to be masked here! Not outside the square bracket anyway, not inside the square bracket, because it directly adjoins the bracket. You have to mask the plus sign.
Test
For the upper school pattern="1[+-]?|[1-5][+-]?|6+?"
1+ 4-5 5-
0,8 4,325 6-
building instruction tenth notes
With comma. Or with dot or comma. The point does not have to be masked here, because it is directly attached to the parenthesis.