I'm trying to validate an entry in a text field via HTML5. Those are the rules:
It can be empty;
If not empty, it must be numeric and start with 21, 29 or 30;
If starts with 21, it must have 13 characters;
If starts with 29, it must have 15 characters;
If starts with 30, it must have 16 characters;
I've got it partially working when I use:
<input type="text" pattern="NULL|^(21)[0-9]{1,13}" />
However, if I try to concatenate those rules, It only works for the first one.
<input type="text" pattern="NULL|^(21)[0-9]{1,13}|^(29)[0-9]{1,15}|^(30)[0-9]{1,16}" />
I'm aware it can be done via a Javascript function, however I'd like to use regex if possible.
There are the two mentioned problems. First, to match an empty input that I assume it is what you want you need to use the ^$ constructor.
Then if you want to limit the required length of the input you need to state the proper length, not a variable one.
A regex like this one should work:
^$|^(21)[0-9]{11}$|^(29)[0-9]{13}$|^(30)[0-9]{14}$
The numbers inside the curly brackets indicate the length of the numeric characters behind the 21, 29 and 30. Those will depend on whether you are counting those as two characters or not for the proper length.
You can test it here and see some examples.
Use
<input type="text" pattern="(?:21\d{11}|29\d{13}|30\d{14})?" />
The HTML5 engine will wrap it with ^(?: and )$ automatically. The regex will look like ^(?:(?:21\d{11}|29\d{13}|30\d{14})?)$ and will match
^ - start of string
(?: - start of a non-capturing group:
21\d{11} - 21 and 11 digits
| - or
29\d{13} - 29 and 13 digits
| - or
30\d{14} - 30 and 14 digits
)? - end of the group, repeat 1 or 0 times
$ - end of string.
Related
I have an HTML form and need to accept orders numbers only with a specific prefix DU-
I am getting a prompt if a random number is entered but also if DU- is used too.
<input type="text" pattern="[^DU-]" title="Order numbers start with DU-" name="orders" class="form2" id="order-ref" placeholder="Please add your order ref"
required>
What is the correct regex to only allow certain order numbers with the prefix DU-
You want to only pass strings that start with DU- and then contain alphanumeric chars.
Use
pattern="DU-[a-zA-Z0-9]+"
It will be translated into ^(?:DU-[a-zA-Z0-9]+)$ pattern and will match
^ - start of string
(?:DU-[a-zA-Z0-9]+) - DU- and then 1 or more ASCII letters or digits
$ - end of string.
If you want to make the pattern more lenient, lax, you may match any one or more non-whitespace chars after DU-:
pattern="DU-\S+"
Or, if you plan to match anything after DU-, use
pattern="DU-.*"
where .* matches any 0 or more chars other than line break chars as many as possible.
I have a password field and I need to check if it has at least 8 characters and if it has the following characters:
! # # $ % ^ & *
I tried to do it using a pattern, and it's not working as expected:
<div class="col-sm-6 form-group">
<input type="password" class="form-control" id="Clave" name="txtClave"
pattern='/[!##$%^&*(),.?":{}|<>]/g.{8,}'
title="Debe contener uno de los siguientes caracteres: ! # # $ % ^ & *, y al menos 8 o más caracteres" required>
</div>
Try Regex: ^(?=.*[!##$%^&*(),.?":{}|<>]).{8,}$
Demo
The best mechanism for combining multiple tests in a single regex is a lookahead. An ordinary regex moves through a string looking for a match, which means that when it finds a match it is no longer at the beginning of the string. A lookahead looks for a match without actually moving (hence the name "lookahead"). The basic format is (?=<regex>) and you can combine as many as you like into a single pattern.
In this case, you have two conditions, so you'll want to combine two lookaheads. We've already seen the first -- .{8,} -- but in a lookahead you want a little more than that: you need to ensure that the regex matches the entire string. So start your pattern with \A, the anchor matching the beginning of the string, and end the lookahead with \z, the anchor matching the end of the string. Put it together and the first part of your pattern is \A(?=.{8,}\z). (This precaution is unnecessary in your specific case, because you'll accept passwords with more than eight characters, but it's still good practice.)
The second condition, matching any of eight specific characters, starts with the class [!##$%^&*]. But in a lookahead that starts at the beginning of the string and never moves, that class would match only the first character. You need a regex that matches anywhere in the string. An easy way to do this is .*[!##$%^&*], which matches zero or more characters followed by one of your special characters. In a lookahead, that would be (?=.*[!##$%^&*]). "Easy" is not always best, however: the .* construct is comparatively inefficient, because it always checks the entire string and then has to backtrack to the beginning before continuing, which can be computationally expensive.
A much more efficient way to do something like this is [^!##$%^&*]*[!##$%^&*]. This matches zero or more characters that are not in your special set, followed by exactly one character that is. (A caret (^) as the first character in a bracketed class means to negate the class; a caret anywhere else in the class is just a literal caret as a member of the class.) It's more efficient because it checks only the characters before its position in the string, and can stop immediately once it finds a match. Putting that in a lookahead gives us (?=[^!##$%^&*]*[!##$%^&*]).
Now you can simply combine the two lookaheads into your "pattern", like so:
pattern='\A(?=.{8,}\z)(?=[^!##$%^&*]*[!##$%^&*])'
That should match any password with eight or more characters, at least one of which is one of your eight special characters: ! # # $ % ^ & *
Is there a way to associate two regex ?
I have this one which prevents user to use this email (test#test.com)
pattern="^((?!test#test.com).)*$"
I also have one which validates email syntax
pattern="[a-z0-9._%+-]{3,}#[a-z]{3,}([.]{1}[a-z]{2,}|[.]{1}[a-z]{2,}[.]{1}[a-z]{2,})"
How to merge those two regex in order to prevent user to user test#test.com and to validate the email syntax ?
I tried to use an OR operator (single pipe) but I am missing something, it doesn't work ...
Thanks !
It seems you may use
pattern="(?!test#test\.com$)[a-z0-9._%+-]{3,}#[a-z]{3,}\.[a-z]{2,}(?:\.[a-z]{2,})?"
Note that the HTML5 patterns are automatically anchored as they are wrapped with ^(?: and )$ at the start/end, so no need adding ^ and $ at the start/end of the pattern.
The (?!test#test\.com$) negative lookahead will fail the match if the input string is equal to the test#test.com string (unlike your first regex that only fails the input that contains the email).
The rest is your second pattern, I only removed {1} that are implicit and contracted an alternation group to a \.[a-z]{2,}(?:\.[a-z]{2,})? where (?:\.[a-z]{2,})? is an optional non-capturing group matching 1 or 0 sequences of . and 2 or more lowercase ASCII letters.
Add A-Z to the character classes to also support uppercase ASCII letters.
I am trying to write a regex for mysql in PHP to find (at least one occurrence of) exactly 3 of the same characters in a row, but not 4 (or more) of the same.
Eg for "000" I want to find:
0//////0/00/ LS///////000
000////0/00/ LS//////////
0//////0/00/ LS////000///
0//////000// LS//////000/
0//////000// LS//00000000
but not:
0//////0000/ LS//////////
0//////0000/ LS//////////
0/////00000/ LS//////////
I have tried the code below which I thought would match 3 zeros preceded and followed by zero or more chars which are not 0, but this resulted in some rows with single 0's and some 000000's
REGEXP '[^0]*[0{3}][^0]*'
Many thanks.
If you plan to use a regex in MySQL, you cannot use lookarounds. Thus, you can use alternation with negated character class and anchors:
(^|[^0])0{3}([^0]|$)
See the regex demo
Explanation:
(^|[^0]) - a group matching either the start of string (^) or a character other than 0
0{3} - exactly 3 zeros
([^0]|$) - a group matching either a character other than 0 or the end of string ($).
I'm trying to make a number input field using the pattern attribute since the regular type number didn't support the validations I needed.
Essentially, I want to allow any numbers that make sense, including $, + or - at the start and a % at the end. Also, users should be able to separate their numbers with commas to avoid mistakes on long numbers, but this is not necessary and they should still be able to submit a long number without any type of separation. The field should also allow for decimals.
<input required pattern="[+-]?\$?\d+(,\d{3})*(\.\d+)?%?" type="text" />
I need to allow for the following examples:
Pass:
2000
-20%
2,000
$2,000.00
999,999,999,999,999,999,999.99
Fail:
123e9
Anything that has letters on it
This is the regex that I have so far, but it doesn't seem to work, even for the most basic numbers. I've been using scriptular to test my regex, but that doesn't seem to reflect the results of the actual HTML validation.
Regex: [+-]?\$?\d+(,\d{3})*(\.\d+)?%?
EDIT: For any Ruby on Rails devs, I realized one of my mistakes is that you must escape any backslashes in your regex when you are generating your text_field. So for example, the regex in the answer should look like (?:\\+|\\-|\\$)?\\d{1,}(?:\\,?\\d{3})*(?:\\.\\d+)?%?
Try with following regex.
Regex: (?:\+|\-|\$)?\d{1,}(?:\,?\d{3})*(?:\.\d+)?%?
Explanation:
(?:\+|\-|\$)? matches either + - or $ in-front of a number which is optional as ? quantifier is used.
\d{1,} matches integer part even if it doesn't have ,.
(?:\,?\d{3})* matches multiple occurrences of comma separated digits if present.
(?:\.\d+)? matches optional decimal part.
%? matches optional % character in the end.
?: stands for non-capturing groups. It will match but won't store it for back-referencing.
Regex101 Demo