I need to find out specific user names that meet a certain - albeit rather wide - criteria. My knowledge at regex is very limited so while my regex constructs did match what I wanted, they also matched about everything else. Can you help me?
The requirements for a valid match are:
string length: exactly 7 characters
contains only alphanumeric characters, mixed upper and lower case, or numbers 0-9
contains at least one number 0-9, can be more than that but never 3 in a row
not all upper case (can be all lower case but never upper case)
Unfortunately, the numbers can be anywhere in the string, and the alphanumeric characters can also be any combination.
Here is an excerpt of the data I need to match:
cgxh21o *
crittaz
Mist246
nOnameR
Gorebag
pu50pce *
rmygy62 *
aeifnz0 *
orp5k1v *
okn5nvr *
The ones marked with * are the ones I want to match. The remaining ones are valid and must not be included.
Is this even possible using regex?
My last attempt was:
/[a-z{0,}A-Z{0,}0-9{1,}]{7}+
but then I found user names that didn't follow that notation at all (more than one number) so it didn't work.
Here's a relatively short and simple regex that will work:
(?=(^.{7}$))(?=.*[a-z])(?=.*\d)(?!.*\d{3})
regex101 demo
Explanation:
(?=(^.{7}$)) check that there's exactly 7 characters (and capture them)
(?=.*[a-z]) at least one lower case letter
(?=.*\d) at least one digit
(?!.*\d{3}) there isn't 3 digits in a row anywhere
Here's a Python demo:
import re
pattern = re.compile(r"(?=(^.{7}$))(?=.*[a-z])(?=.*\d)(?!.*\d{3})")
ls = ["cgxh21o", "crittaz", "Mist246", "nOnameR", "Gorebag",
"pu50pce", "rmygy62", "aeifnz0", "orp5k1v", "okn5nvr",
"OKN5NVR", "short1", "aeifnz0aaaaaa", "12CeE12"]
for elem in ls:
print(elem, bool(re.search(pattern, elem)))
Output:
cgxh21o True
crittaz False
Mist246 False
nOnameR False
Gorebag False
pu50pce True
rmygy62 True
aeifnz0 True
orp5k1v True
okn5nvr True
OKN5NVR False
short1 False
aeifnz0aaaaaa False
12CeE12 True
You could use lookahead assertions:
^(?=[^a-z\s]*[a-z])(?=[^\d\s]*\d)(?!.*\d{3})[a-zA-Z0-9]{7}$
Explanation
^ Start of string
(?=[^a-z\s]*[a-z]) Assert a lowercase char a-z
(?=[^\d\s]*\d) Assert a digit
(?!.*\d{3}) Assert not 3 digits in a row
[a-zA-Z0-9]{7} Match 7 times any of the listed
$ End of string
Regex demo
Here's a possibility based on your updated question:
^(?![a-zA-Z]{7}|.*[0-9]{3}.*|[A-Z0-9]{7})([a-zA-Z0-9]){7}$
Doesn't match
crittaz
nOnameR
Gorebag
ABCDEFG
aBCDEFG
1234567
Mist246
ABCDEF7
Matches
cgxh21o
pu50pce
rmygy62
aeifnz0
orp5k1v
okn5nvr
There's probably a number of ways to do this. This one looks for 7 alphanumeric, but not if there's only 7 alphabetic, not if there's only uppercase and numbers, and not if there's 3 digits in a row...
Related
I'm trying to make
09-546-943
fail in the below regex pattern.
^[0-9]{2,3}[- ]{0,1}[0-9]{3}[- ]{0,1}[0-9]{3}$
Passing criteria is
greater than 10-000-000 or 010-000-000 and
less than 150-000-000
The tried example "09-546-943" passes. This should be a fail.
Any idea how to create a regex that makes this example a fail instead of a pass?
You may use
^(?:(?:0?[1-9][0-9]|1[0-4][0-9])-[0-9]{3}-[0-9]{3}|150-000-000)$
See the regex demo.
The pattern is partially generated with this online number range regex generator, I set the min number to 10 and max to 150, then merged the branches that match 1-8 and 9 (the tool does a bad job here), added 0? to the two digit numbers to match an optional leading 0 and -[0-9]{3}-[0-9]{3} for 10-149 part and -000-000 for 150.
See the regex graph:
Details
^ - start of string
(?: - start of a container non-capturing group making the anchors apply to both alternatives:
(?:0?[1-9][0-9]|1[0-4][0-9]) - an optional 0 and then a number from 10 to 99 or 1 followed with a digit from 0 to 4 and then any digit (100 to 149)
-[0-9]{3}-[0-9]{3} - a hyphen and three digits repeated twice (=(?:-[0-9]{3}){2})
| - or
150-000-000 - a 150-000-000 value
) - end of the non-capturing group
$ - end of string.
This expression or maybe a slightly modified version of which might work:
^[1][0-4][0-9]-[0-9]{3}-[0-9]{3}$|^[1][0]-[0-9]{3}-[0-9]{2}[1-9]$
It would also fail 10-000-000 and 150-000-000.
In this demo, the expression is explained, if you might be interested.
This pattern:
((0?[1-9])|(1[0-4]))[0-9]-[0-9]{3}-[0-9]{3}
matches the range from (0)10-000-000 to 149-999-999 inclusive. To keep the regex simple, you may need to handle the extremes ((0)10-000-000 and 150-000-000) separately - depending on your need of them to be included or excluded.
Test here.
This regex:
((0?[1-9])|(1[0-4]))[0-9][- ]?[0-9]{3}[- ]?[0-9]{3}
accepts (space) or nothing instead of -.
Test here.
I have to define a Membership ID which is a string of 3 characters which can have lower/upper case letters and digits.
For instance AA2 and 2AA or A22 are valid regular expressions. It does not matter the position, I need to make sure there is at least one digit in the string.
The current expression is this ([a-z]|[A-Z]|[0-9]){3} . What should I add as a "condition" to look for a digit?
Thank you in advance,
Liviu
You can use a lookahead like this:
^(?=[A-Za-z]*[0-9])[A-Za-z0-9]{3}$
(?=[A-Za-z]*[0-9]) is a positive lookahead to assert we have at least a digit after 0 or more alphabets.
Read more about lookarounds in regex
You can separate conditions:
cond.1 and cond.2 would be true only if the both are true that's means that at the cond.1 we check if string contains 3 chars and in the cond.2 we check if it contains a number:
var a=/([a-zA-Z]|[0-9]){3}/g
var b=/([0-9]){1,2}/g
if(a && b){
//return true only if the word contains 3 characters and including at least a number
}
I would very much appreciate a bit of help with the following regex riddle.
I need regex statement that would validate against the following rules:
The input can contain letters, special characters and digits.
The input can't start with "0",
The input Can have up to 7 digits
Examples of valid input:
aa1234aa2.(less than 7 digits)
asd234566 (less than 7 digits)
Examples of invalid input:
0asdfd92 (starts with 0)
asd12312311 (more than 7 digits)
What I have tried so far:
^\D[0-9]{0,7}$,
validates against d0000000, but the input may be d0d0dddd1234d
The part can't start with 0 can be removed from the requirement if it complicates a lot. The most important is to have "Can have up to 7 digits" part.
Regards,
Oleg
This is what you need!
Attempt 1: ^[1-9]\d{0,6}$
Attempt 2: ^[^0][\d\w]{0,6}$
Attempt 3: ^[^0].{0,6}$
Attempt 4: ^([\D]*\d){0,7}[\D]*$
Attempt 5: ^([\D]*[1-9]){0,7}[\D]*$|^[^0]\d{0,6}$
Attempt 6: ^([\D]*[1-9]){1,7}[\D]*$|^[^0]\d{1,6}$ <- this should work
Example here
If I understand the requirements correctly, this will work:
^(?=[^0])(\D*\d){0,7}\D*$
That will allow any string that does not start with a zero and has 7 or fewer digits. Any other characters are allowed in any quantity.
Explanation
The first part (?=[^0]) is an assertion that checks to make sure the string does not start with zero. The rest matches any number of non-digits followed by a digit, up to 7 times. Then any number of non-digits before the end of the string.
Assuming Perl (it looks like Perl regular expressions):
Check for leading zero: if (subst($pass, 0, 1) eq '0') { fail }
Check for no more than seven digits: if (($pass =~ tr /0-9/0-9/) > 7) { fail }
I'm generally against trying to cram everything into a single regular expression, especially when there are other tools available to do the job. In this case, the tr will not be executed if there is a leading zero, and a leading zero is easy to spot in the beginning of a string.
Doing it this way, it's easy to add further restrictions independently of the others. For example, "there may be more than 7 digits if they are all separated by other types of characters" (a regex for this one, probably).
You can use this regex:
^[^0](?:\D*\d){1,7}\D*$
RegEx Demo
This will perform following validations:
Must start with non-zero
Has 1 to 7 digits after first char
Verbose, but does the trick.
(^[1-9][^\d]*([\d]?[^\d]*){0,6}$|^[^\d]+([\d]?[^\d]*){0,7}$)
I found it easier to split the RegEx into two cases: when the string starts with a digit, and when it doesn't.
^((?:\D+(?:\d?\D*){0,7})|(?:[1-9]\D*(?:\d?\D*){0,6}))$
You can test it here
I have this regex to allow for only alphanumeric characters.
How can I check that the string at least contains 3 alphabet characters as well.
My current regex,
if(!/^[a-zA-Z0-9]+$/.test(val))
I want to enforce the string to make sure there is at least 3 consecutive alphabet characters as well so;
111 // false
aaa1 // true
11a // false
bbc // true
1a1aa // false
+ means "1 or more occurrences."
{3} means "3 occurrences."
{3,} means "3 or more occurrences."
+ can also be written as {1,}.
* can also be written as {0,}.
To enforce three alphabet characters anywhere,
/(.*[a-z]){3}/i
should be sufficient.
Edit. Ah, you'ved edited your question to say the three alphabet characters must be consecutive. I also see that you may want to enforce that all characters should match one of your "accepted" characters. Then, a lookahead may be the cleanest solution:
/^(?.*[a-z]{3})[a-z0-9]+$/i
Note that I am using the case-insensitive modifier /i in order to avoid having to write a-zA-Z.
Alternative. You can read more about lookaround assertions here. But it may be a little bit over your head at this stage. Here's an alternative that you may find easier to break down in terms of what you already know:
/^([a-z0-9]*[a-z]){3}[a-z0-9]*$/i
This should do the work:
^([0-9]*[a-zA-Z]){3,}[0-9]*$
It checks for at least 3 "Zero-or-more numerics + 1 Alpha" sequences + Zero-or-more numerics.
You want to match zero or more digits then 3 consecutive letters then any other number of digits?
/\d*(?:[a-zA-Z]){3,}\d*/
This is vanilla JS you guys can use. My problem is solved using this.
const str = "abcdggfhf";
const pattern = "fhf";
if(pattern.length>2) {
console.log(str.search(pattern));
}
I am having a bit of difficulty with the following:
I need to allow any positive numeric value up to four decimal places. Here are some examples.
Allowed:
123
12345.4
1212.56
8778787.567
123.5678
Not allowed:
-1
12.12345
-12.1234
I have tried the following:
^[0-9]{0,2}(\.[0-9]{1,4})?$|^(100)(\.[0]{1,4})?$
However this doesn't seem to work, e.g. 1000 is not allowed when it should be.
Any ideas would be greatly appreciated.
Thanks
To explain why your attempt is not working for a value of 1000, I'll break down the expression a little:
^[0-9]{0,2} # Match 0, 1, or 2 digits (can start with a zero)...
(\.[0-9]{1,4})?$ # ... optionally followed by (a decimal, then 1-4 digits)
| # -OR-
^(100) # Capture 100...
(\.[0]{1,4})?$ # ... optionally followed by (a decimal, then 1-4 ZEROS)
There is no room for 4 digits of any sort, much less 1000 (theres only room for a 0-2 digit number or the number 100)
^\d* # Match any number of digits (can start with a zero)
(\.\d{1,4})?$ # ...optionally followed by (a decimal and 1-4 digits)
This expression will pass any of the allowed examples and reject all of the Not Allowed examples as well, because you (and I) use the beginning-of-string assertion ^.
It will also pass these numbers:
.2378
1234567890
12374610237856987612364017826350947816290385
000000000000000000000.0
0
... as well as a completely blank line - which might or might not be desired
to make it reject something that starts with a zero, use this:
^(?!0\d)\d* # Match any number of digits (cannot "START" with a zero)
(\.\d{1,4})?$ # ...optionally followed by (a decimal and 1-4 digits)
This expression (which uses a negative lookahead) has these evaluations:
REJECTED Allowed
--------- -------
0000.1234 0.1234
0000 0
010 0.0
You could also test for a completely blank line in other ways, but if you wanted to reject it with the regex, use this:
^(?!0\d|$)\d*(\.\d{1,4})?$
Try this:
^[0-9]*(?:\.[0-9]{0,4})?$
Explanation: match only if starting with a digit (excluding negative numbers), optionally followed by (non-capturing group) a dot and 0-4 digits.
Edit: With this pattern .2134 would also be matched. To only allow 0 < x < 1 of format 0.2134, replace the first * with a + above.
This regex would do the trick:
^\d+(?:\.\d{1,4})?$
From the beginning of the string search for one or more digits. If there's a . it must be followed with atleast one digit but a maximum of 4.
^(?<!-)\+?\d+(\.?\d{0,4})?$
The will match something with doesn't start with -, maybe has a + followed by an integer part with at least one number and an optional floating part of maximum 4 numbers.
Note: Regex does not support scientific notation. If you want that too let me know in a comment.
Well asked!!
You can try this:
^([0-9]+[\.]?[0-9]?[0-9]?[0-9]?[0-9]?|[0-9]+)$
If you have a double value but it goes to more decimal format and you want to shorter it to 4 then !
double value = 12.3457652133
value =Double.parseDouble(new DecimalFormat("##.####").format(value));