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));
}
Related
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...
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 need a RegEx pattern that will return the first N words using a custom word boundary that is the normal RegEx white space (\s) plus punctuation like .,;:!?-*_
EDIT #1: Thanks for all your comments.
To be clear:
I'd like to set the characters that would be the word delimiters
Lets call this the "Delimiter Set", or strDelimiters
strDelimiters = ".,;:!?-*_"
nNumWordsToFind = 5
A word is defined as any contiguous text that does NOT contain any character in strDelimiters
The RegEx word boundary is any contiguous text that contains one or more of the characters in strDelimiters
I'd like to build the RegEx pattern to get/return the first nNumWordsToFind using the strDelimiters.
EDIT #2: Sat, Aug 8, 2015 at 12:49 AM US CT
#maraca definitely answered my question as originally stated.
But what I actually need is to return the number of words ≤ nNumWordsToFind.
So if the source text has only 3 words, but my RegEx asks for 4 words, I need it to return the 3 words. The answer provided by maraca fails if nNumWordsToFind > number of actual words in the source text.
For example:
one,two;three-four_five.six:seven eight nine! ten
It would see this as 10 words.
If I want the first 5 words, it would return:
one,two;three-four_five.
I have this pattern using the normal \s whitespace, which works, but NOT exactly what I need:
([\w]+\s+){<NumWordsOut>}
where <NumWordsOut> is the number of words to return.
I have also found this word boundary pattern, but I don't know how to use it:
a "real word boundary" that detects the edge between an ASCII letter
and a non-letter.
(?i)(?<=^|[^a-z])(?=[a-z])|(?<=[a-z])(?=$|[^a-z])
However, I would want my words to allow numbers as well.
IAC, I have not been able how to use the above custom word boundary pattern to return the first N words of my text.
BTW, I will be using this in a Keyboard Maestro macro.
Can anyone help?
TIA.
All you have to do is to adapt your pattern ([\w]+\s+){<NumWordsOut>} to, including some special cases:
^[\s.,;:!?*_-]*([^\s.,;:!?*_-]+([\s.,;:!?*_-]+|$)){<NumWordsOut>}
1. 2. 3. 4. 5.
Match any amount of delimiters before the first word
Match a word (= at least one non-delimiter)
The word has to be followed by at least one delimiter
Or it can be at the end of the string (in case no delimiter follows at the end)
Repeat 2. to 4. <NumWordsOut> times
Note how I changed the order of the -, it has to be at the start or end, otherwise it needs to be escaped: \-.
Thanks to #maraca for providing the complete answer to my question.
I just wanted to post the Keyboard Maestro macro that I have built using #maraca's RegEx pattern for anyone interested in the complete solution.
See KM Forum Macro: Get a Max of N Words in String Using RegEx
I found somewhat similar questions
R - Select string text between two values, regex for n characters or at least m characters,
but I'm still having trouble
say I have a string in r
testing_String <- "AK ADAK NAS PADK ADK 70454 51 53N 176 39W 4 X T 7"
And I need to be able to pull anything between the first element in the string that contains 2 characters (AK) and PADK,ADK. PADK and ADK will change in character but will always be 4 and 3 characters in length respectively.
So I would need to pull
ADAK NAS
I came up with this but its picking up everything from AK to ADK
^[A-Za-z0_9_]{2}(.*?) +[A-Za-z0_9_]{4}|[A-Za-z0_9_]{3,}
If I understood your question correctly, this should do the trick:
\b[A-Z]{2}\s+(.+?)\s+[A-Z]{4}\s+[A-Z]{3}\b
Demo
You'll have to switch the perl = TRUE option (to use a decent regex engine).
\b means word boundary. So this pattern looks for a match starting with a 2-letter word and ending with a 4 letter word followed by a 3 letter word. Your value will be in the first group.
Alternatively, you can write the following to avoid using the capturing group:
\b[A-Z]{2}\s+\K.+?(?=\s+[A-Z]{4}\s+[A-Z]{3}\b)
But I'd prefer the first method because it's easier to read.
Lookbehind is supported for perl=TRUE, so this regex will do what you want:
(?<=\w{2}\s).*?(?=\s+[^\s]{4}\s[^\s]{2})