I have the following regex:
#^(?=.{8,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\W).*$#
This regex matches a string that contains at least one each of the groups a-z A-Z 0-9 and special chars.
Is it possible to write a regex to match at minimum 3 from 4 sub pattern (One preg_match, not multiple) ?
For example, the string should match A-Z, 0-9 and a-z or A-Z, 0-9 and a special char.
But also 4/4 should be allowed.
Of course you can have only three out of four conditions, just write an alternation with all possibilities:
/^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*\W)|...|...|...).{8,20}$/
I just wrote 2 alternatives, too complicated. You need to fill the ... parts by yourself.
I would suggest you don't do that with a single regex. It gets complicated and is error prone. Test the conditions separately and count how many are matched.
Related
I have a filename i need to validate using preg_match in PHP, but i dont know much about regex patterns to fix my issue.
The string i am trying to validate is
2 numbers (0-9), a comma, 2 numbers (0-9), a hyphen, 2 numbers (0-9), a comma, 2 numbers (0-9)
An example is 47,60-51,00
I have tried the following
(-)?[0-9]+((,|-)[0-9]+)*
and
^[0-9][0-9,-]-[0-9,-][0-9]$
But both seem to fail one way or another. Could someone help point me in the right direction
You want to match the comma as a separate match but adding it to a character class [0-9,-] it can also match a digit or -
To match that format in a more specific way, you could use this pattern with a quantifier {2} to repeat matching a digit and match the comma's and hyphen at the expected position.
^[0-9]{2},[0-9]{2}-[0-9]{2},[0-9]{2}$
Regex demo
If you want the match to start with an optional hyphen you could start the pattern with ^-?
I'm trying to create regex, which will match 4 digits and 2 letters in any order. Letters can be in lower and upper cases.
Example:
a1234B
17AF45
aR1307
Any advice would be appreciated.
Thanks.
A brute force approach to this might be to just use two positive lookaheads:
^(?=.*[A-Za-z].*[A-Za-z])(?=.*\d.*\d.*\d.*\d).{6}$
This would match exactly two letters, lowercase or uppercase, and four digits, for a total of six characters.
Demo
For a deeper explanation, consider the first lookahead:
^(?=.*[A-Za-z].*[A-Za-z])
This says to assert (but not match) from the start of the string that two letters occur anywhere in the string. Assuming this is true, then the regex engine will evaluate the next lookahead, which checks for four numbers. If that also be true, then all that is needed is to match any 6 characters. Those matching characters must only letters and numbers, due to the lookaheads.
I am using this tool http://regexr.com/3fvg9
I want to mark this (weat)her in regexxr tool.
(weath)er is good. // i want to mark this word
(weather is go)od. // i want to mark this word
Please help me.
Since there is no way to check with a regex if a word is "known" or not, I suggest extracting these parts you need first and then use a kind of a spelling dictionary to check if the words are correct. It won't be 100% accurate, but still better than pure regex.
The expression you need to extract the parts of glued words with parentheses is
(?|([a-zA-Z0-9]+)\(([a-zA-Z\s]+)\)|\(([a-zA-Z\s]+)\)([a-zA-Z0-9]+))
See the regex demo at regex101 that supports PHP regex.
The regex matches 2 alternatives inside a branch reset group inside which all capturing groups in different branches are numbered starting with the same ID:
([a-zA-Z0-9]+)\(([a-zA-Z\s]+)\) - Group 1 (([a-zA-Z0-9]+)) matching 1+ alphanumeric chars, then (, and then Group 2 (([a-zA-Z\s]+)) matching 1+ letters and whitespaces and then a ) is matched
| - or
\(([a-zA-Z\s]+)\)([a-zA-Z0-9]+) - a (, then Group 1 (([a-zA-Z\s]+)) matching 1+ letters and whitespaces, ), and then Group 2 (([a-zA-Z0-9]+)) matching 1+ alphanumeric chars
Assuming I have a set of numbers (from 1 to 22) divided by some trivial delimiters (comma, point, space, etc). I need to make sure that this set of numbers does not contain any repetition of the same number. Examples:
1,14,22,3 // good
1,12,12,3 // not good
Is it possible to do via regular expression?
I know it's easy to do using just php, but I really wander how to make it work with regex.
Yes, you could achieve this through regex via negative looahead.
^(?!.*\b(\d+)\b.*\b\1\b)\d+(?:,\d+)+$
(?!.*\b(\d+)\b.*\b\1\b) Negative lookahead at the start asserts that the there wouldn't be a repeated number present in the match. \b(\d+)\b.*\b\1\b matches the repeated number.
\d+ matches one or more digits.
(?:,\d+)+ One or more occurances of , , one or more digits.
$ Asserts that we are at the end .
DEMO
OR
Regex for the numbers separated by space, dot, comma as delimiters.
^(?!.*\b(\d+)\b.*\b\1\b)\d+(?:([.\s,])\d+)(?:\2\d+)*$
(?:([.\s,])\d+) capturing group inside this non-capturing group helps us to check for following delimiters are of the same type. ie, the above regex won't match the strings like 2,3 5.6
DEMO
You can use this regex:
^(?!.*?(\b\d+)\W+\1\b)\d+(\W+\d+)*$
Negative lookahead (?!.*?(\b\d+)\W+\1\b) avoids the match when 2 similar numbers appear one after another separated by 1 or more non-word characters.
RegEx Demo
Here is the solution that fit my current need:
^(?>(?!\2\b|\3\b)(1\d{1}|2[0-2]{1}|\d{1}+)[,.; ]+)(?>(?!\1\b|\3\b)(1\d{1}|2[0-2]{1}|\d{1}+)[,.; ]+)(?>(?!\1\b|\2\b)(1\d{1}|2[0-2]{1}|\d{1}+))$
It returns all the sequences with unique numbers divided by one or more separator and also limit the number itself from 1 to 22, allowing only 3 numbers in the sequence.
See working example
Yet, it's not perfect, but work fine! Thanks a lot to everyone who gave me a hand on this!
My regex at the minute is like this
'/[a-z0-9]{40}/i'
Which will match any string with no spaces that contains letters and/or numbers.
How can I change it so that it must at least include at least one number and at least one alphabet character so that if the string was all numbers or all letters it would not be matched?
Thanks
/([:alpha:].*[:digit:]|[:digit:].*[:alpha:])/
This requires a number to follow a letter, or a letter to follow a number.
From your original regex, it appears that you want to enforce a requirement for 40 characters total. For that, try:
/^(.*[:alpha:].*[:digit:].*|.*[:digit:].*[:alpha:].*){40}$/
Note the extra .*'s. As long as there's one alpha and one digit, the other characters can be anything. As long as there are 40 of them.
If you want to avoid matching whitespace, replace each .* with [^[:space:]]*.