I am having problems creating a regular expresion. It needs to fullfill the following:
1) Has 8-12 characters
2) At least 1 uppercase letter
3) At least 3 lowercase letters
4) At least 1 number
5) At least 1 special character
6) Has to start with a lowercase, upercase or numeric
7) Maximum of 2 repeating characters
Thanks in advance!
This should work
^(?=.*[A-Z])(?=(?:.*[a-z]){3})(?=.*[0-9])(?=.*[!"#$%&'()*+,\-./:;<=>?#[\]^_`{|}~])(?=(?:(.)(?!\1\1))+$)[a-zA-Z0-9].{7,11}$
Explained / Expanded
^ # BOS
(?= .* [A-Z] ) # 1 upper
(?=
(?: .* [a-z] ){3} # 3 lower
)
(?= .* [0-9] ) # 1 number
(?=
.* [!"#$%&'()*+,\-./:;<=>?#[\]^_`{|}~] # 1 special
)
(?= # Maximum 2 repeating
(?:
( . ) # (1)
(?! \1 \1 )
)+
$
)
[a-zA-Z0-9] # First alnum
.{7,11} # 8 to 12 max chars
$ # EOS
What you got so far?
Also, which set of regex are you using ?
I'd start with the length of the expression
Restrict it to be 8-12, something like [a-zA-Z]{8,12}
For the requirements on the first one you can use a []+
For the other requirements it's a little tricker
Related
I have a Pattern: (^([-]?\d+([.]\d+)?,){6}([10],)([-]?\d+([.]\d+)?)$) which matches: "26.9841,300.007666,4,1,0,15,1,0" this is what I want, however my pattern does not match the following Strings:
"26 . 9841,300 . 007666,4,1,0,15,1,0"
"26.9841\n,300.007666\n,4,\n1,0,15,1,0"
"2 6 . 9 8 4 1 ,\n 3 0 0 .0 0 7 6 6 6 , 4 \n, 1 , 0 , 1 5 , 1 , 0"
Which is the exact same String just with random Spaces and New Lines thrown in.
I could match those with the following Pattern:
(^([-]?\s*?\n*?[0-9 ]+\s*?\n*?(\s*?\n*?[.]\s*?\n*?[0-9 ]+\s*?\n*?)?\s*?\n*?,\s*?\n*?){6}([10]\s*?\n*?,)(\s*?\n*?[-]?\s*?\n*?[0-9 ]+\s*?\n*?([.]\s*?\n*?[0-9 ]+\s*?\n*?)?)$)
Which matches 1, 2, and 3, however this pattern is absurd, most likely can be simplified, and doesn't match all New lines; (it won't match New Line occurrence in [0-9]+ (+) chunks). It's also just slapping "\s*?\n*?" wherever it can.
Question
What I want to know is if there is a way to match through those characters. Ignoring their occurrence, as long as you can say, if they weren't there the Pattern would match.
Note:
Input String should match: ((Decimal|Int),{6}(1|0),(Decimal|Int))
If New line characters appear at the end of the pattern assume that no more input can be found.
I cannot remove those characters from the input String as I need to know that they were there.
I do not care about leading or trailing spaces/new-lines
Pattern will always start with "-" or "[0-9]" (yes 0 can be the first char)
Pattern will always end with [0-9]
Edit
This Regex works and passes my test suite: (^(-?\s*[0-9]\s*[\s.0-9]*,){6}(\s*[10]\s*,)(\s*-?\s*[0-9][\s.0-9]*?)$)
If you wish to have a test that is a little more of a validation,
this would be more appropriate.
However, anytime you intersperse white space \s construct in a regex that
separates alike clusters (?:\s*\d)+ when this looks like most of your data,
there is a risk of no way points from which to end the search.
This particular regex might work though.
^\s*((?:\s*[-]?(?:\s*\d)+(?:\s*[.](?:\s*\d)+)?\s*,){6}\s*[10]\s*,\s*[-]?(?:\s*\d)+?(?:\s*[.](?:\s*\d)+?)?)$
https://regex101.com/r/YmKJgW/1
The capture group 1 is a convenience that strips leading white space from the match.
^
\s*
( # (1 start)
(?:
\s* [-]?
(?: \s* \d )+
(?:
\s* [.]
(?: \s* \d )+
)?
\s* ,
){6}
\s*
[10] \s* , \s*
[-]?
(?: \s* \d )+?
(?:
\s* [.]
(?: \s* \d )+?
)?
) # (1 end)
$
I am trying to validate a comma separated list of numbers 1-31 unique (not repeating).
i.e.
2,4,6,7,1 is valid input.
2,2,6 is invalid
2 is valid
2, is invalid
1,2,3,4,15,6,7,31 is valid
1,2,3,4,15,6,7,32 is invalid
20,15,3
I tried
^((([0]?[1-9])|([1-2][0-9])|(3[01]))(?!([0]?[1-9])|([1-2][0-9])|(3[01])*,\\1(?!([0]?[1-9])|([1-2][0-9])|(3[01])) but it's accepting repeating numbers
For a number range that exceeds 1 digit, just add word boundary's around
the capture group and the back reference.
This isolates a complete number.
This particular one is numb range 1-31
^ # BOS
(?! # Validate no dups
.*
( # (1 start)
\b
(?: [1-9] | [1-2] \d | 3 [0-1] ) # number range 1-31
\b
) # (1 end)
.*
\b \1 \b
)
(?: [1-9] | [1-2] \d | 3 [0-1] ) # Unrolled-loop, match 1 to many numb's
(?: # in the number range 1-31
,
(?: [1-9] | [1-2] \d | 3 [0-1] )
)*
$ # EOS
var data = [
'2,4,6,7,1',
'2,2,6',
'2,30,16,3',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(function(str) {
document.write(str + ' gives ' + /^(?!.*(\b(?:[1-9]|[1-2]\d|3[0-1])\b).*\b\1\b)(?:[1-9]|[1-2]\d|3[0-1])(?:,(?:[1-9]|[1-2]\d|3[0-1]))*$/.test(str) + '<br/>');
});
I have created a pattern that can do this.
The pattern:^((?!(\d+),[^\n]*\b\2\b)([1-9]\b|[1-2]\d|3[0-1])(,(?1))?)$
A demo.
A short description.
^ - matches start of a line
(?!(\d+),[^\n]*\b\2\b) - Looks ahead to ensure the next number is not repeated
(\d+) - grab next number
,[^\n]* - a comma followed by anything but a new line
\b\2\b - The next number again repeated
([1-9]\b|[1-2]\d|3[0-1]) - Checks next number between 1-31
[1-9]\b - Checks for single digit. Boundary used so to prevent two digit numbers matching.
[1-2]\d - Checks for 10-29
3[0-1] - Checks for 30,31
(,(?1))?) If followed by comma recurse on main pattern to check if next number is repeated.
, - checks followed by acomma
(?1) - recurses on main pattern.
$ - End of line
Updated: Forgot to check 1-31
I totally agree that there are much better ways than regex to look for duplicates, but if you must do this as regex, here's a way (depending on your regex flavor).
See on regex101 (I have made it multiline and extended just for testing and readability).
^
(?!.*\b(\d+)\b.*\b\1\b)
(0?[1-9]|[12][0-9]|3[01])
(,(0?\d|[12][0-9]|3[01]))*
$
Explanation:
(?!.*\b(\d+)\b.*\b\1\b) is a negative lookahead to ensure there are no duplicates
(0?[1-9]|[12][0-9]|3[01]) matches the first number
(,(0?\d|[12][0-9]|3[01]))* matches any more
Note: updated to use word boundaries - based on answer from #sln
I've the following regex:
/(\(*)?(\d+)(\)*)?([+\-*\/^%]+)(\(*)?(\)*)?/g
I have the following string:
(5+4+8+5)+(5^2/(23%2))
I use the regex to add space between numbers, arithmetic operators and parentheses.
I do that like:
\1 \2 \3 \4 \5 \6
That turns the string into:
( 5 + 4 + 8 + 5 ) + ( 5 ^ 2 / ( 23 % 2))
As you can see the last two parentheses don't get spaced.
How can I make them space as well?
The output should look like:
( 5 + 4 + 8 + 5 ) + ( 5 ^ 2 / ( 23 % 2 ))
Try out the regex here.
You could try a simple and fast solution
edit
Some tips:
I know you are not validating the simple math expressions, but it would not hurt to do that before trying to beautify.
Either way you should remove all whitespace ahead of time
Find \s+ Replace nothing
To condense summation symbols you could do:
Find (?:--)+|\++ Replace +
Find [+-]*-+* Replace -
Division and power symbol meaning will vary with implementation,
and to condense them is not advisable, and better to just validate the form.
Validation is the more complex feat complicated by the meaning of parenthesis,
and their balance. That is another topic.
A minimum character validation should be done though.
String must be matched by ^[+\-*/^%()\d]+$ at least.
After optionally doing the above, run the beautifier on it.
https://regex101.com/r/NUj036/2
Find ((?:(?<=[+\-*/^%()])-)?\d+(?!\d)|[+\-*/^%()])(?!$))
Replace '$1 '
Explained
( # (1 start)
(?: # Allow negation if symbol is behind it
(?<= [+\-*/^%()] )
-
)?
\d+ # Many digits
(?! \d ) # - don't allow digits ahead
| # or,
[+\-*/^%()] # One of these operators
) # (1 end)
(?! $ ) # Don't match if at end of string
You can try something like this based on word boundaries and on non-word characters:
\b(?!^|$)|\W\K(?=\W)
and replace with a space.
demo
details:
\b # a word-boundary
(?!^|$) # not at the start or at the end of the string
| # OR
\W # a non-word character
\K # remove characters on the left from the match result
(?=\W) # followed by a non-word character
You can test everything out here:
I would like to extract the value of individual variables paying attention to the different ways they have been defined. For example, for dtime we want to extract 0.004. It also has to be able to interpret exponential numbers, like for example for variable vis it should extract 10e-6.
The problem is that each variable has its own number of white spaces between the variable name and the equal sign (i dont have control on how they have been coded)
Text to test:
dtime = 0.004D0
case = 0
newrun = 1
periodic = 0
iscalar = 1
ieddy = 1
mg_level = 5
nstep = 20000
vis = 10e-6
ak = 10e-6
g = 9.81D0
To extract dtime's value this REGEX works:
(?<=dtime =\s)[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
To extract dtime's value this REGEX works:
(?<=vis =\s)[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
The problem is that I need to know the exact number of spaces between the variable name and the equal sign. I tried using \s+ but it does not work, why?
(?<=dtime\s+=\s)[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
If you are using PHP or PERL or more generally PCRE then you can use the \K flag to solve this problem like this:
dtime\s+=\s\K[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
^^
Notice the \K, it tells the expression to ignore everything
behind it as if it was never matched
Regex101 Demo
Edit: I think you need to capture the number in a capturing group if you can't use look behinds or eliminate what was matched so:
dtime\s*=\s*([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)
(?<=dtime\s+=\s) is a variable length lookbehind because of \s+. Most(not all) engines support only a 'fixed' length lookbehind.
Also, your regex requires a digit before the exponential form, so if there is no digit, it won't match. Something like this might work -
# dtime\s*=\s*([-+]?[0-9]*\.?[0-9]*(?:[eE][-+]?[0-9]+)?)
dtime \s* = \s*
( # (1)
[-+]? [0-9]* \.? [0-9]*
(?: [eE] [-+]? [0-9]+ )?
)
Edit: After review, I see you're trying to fold multiple optional forms into one regex.
I think this is not really that straight forward. Just as interest factor, this is probably a baseline:
# dtime\s*=\s*([-+]?(?(?=[\d.]+)(\d*\.\d+|\d+\.\d*|\d+|(?!))|)(?(?=[eE][-+]?\d+)([eE][-+]?\d+)|))(?(2)|(?(3)|(?!)))
dtime \s* = \s*
( # (1 start)
[-+]? # optional -+
(?(?= # conditional check for \d*\.\d*
[\d.]+
)
( # (2 start), yes, force a match on one of these
\d* \. \d+ # \. \d+
| \d+ \. \d* # \d+ \.
| \d+ # \d+
| (?!) # or, Fail the match, the '.' dot is there without a number
) # (2 end)
| # no, match nothing
)
(?(?= # conditional check for [eE] [-+]? \d+
[eE] [-+]? \d+
)
( [eE] [-+]? \d+ ) # (3), yes, force a match on it
| # no, match nothing
)
) # (1 end)
(?(2) # Conditional check - did we match something? One of grp2 or grp3 or both
| (?(3)
| (?!) # Did not match a number, Fail the match
)
)
I'm a newbie to regex and trying to create a regex to validate pass phrases. I would like to validate that the pass phrase has:
n number of words or more
words should be separated by spaces
words, each with n characters or more
a number in at least one of the words
at least one special character in one of the words
This is what what I have so far
^(?=.*?((?:.*?\b[a-zA-Z0-9]{2,40}\b)\s*){3,})(?=.*?[##$%^&+=])(?=.*?[0-9]).*$
It matches this Pe2sI#sHy?ThYulU# phrase that does not have at least 3 words (no spaces). What am I doing wrong?
You should use \s+ instead of \s*. The latter allows zero spaces, the former requires at least one. But your regex is overly complicated. Try this:
^ # Start of string
(?=.*\d) # Assert at least one digit
(?=.*[##$%^&+=]) # Assert at least one special char
\s* # Optional leading whitespace
(?: # Match...
\S{2,} # at least 2 non-spaces
\s+ # at least 1 whitespace
){2,} # at least 2 times
\S{2,} # Match at least 2 non-spaces (making 3 "words" minimum)
A little late to this, so this is just an observation.
This is a take-off on #Tim Pietzcker's method.
Although 'words' can be anything, if you want to require at least
3 words have [a-zA-Z0-9]{2,40} characters imbedded, you could do this.
^ # String start
(?=.*[##$%^&+=]) # Assert 1 special char
(?=.*\d) # Assert 1 digit
(?: # Special 'Word Group' -- Need 2 words
.* # Any char, 0 or more times
[a-zA-Z0-9]{2,40} # Alpha/num char, 2 to 40 times
.* # Any char, 0 or more times
\s # a whitespace, only 1 required
){2} # 'Word Group' end, do 2 times
.* # Any char, 0 or more times
[a-zA-Z0-9]{2,40} # Alpha/num char, 2 to 40 times -- Need 1 word
This should match at least 3 special [a-zA-Z0-9]{2,40} words separated by at least 1 space
including a digit and special character.
update
Yes, you can combine it into a single group done {3} times in 2 ways I know of.
Use a capture buffer as a flag
^(?=.*[##$%^&+=])(?=.*\d)(?:(?:(?!\1)|\s).*[a-zA-Z0-9]{2,40}().*){3}
^ ^
---------------------------------------
^ # String start
(?=.*[##$%^&+=]) # Assert 1 special char
(?=.*\d) # Assert 1 digit
(?: # Special 'Word Group'
(?: #.. grping start ....
(?!\1) # Either capt group 1 is UN-DEFINED
| \s # OR, require a whitespace
) #.. grping end ....
.* # Any char, 0 or more times
[a-zA-Z0-9]{2,40} # Alpha/num char, 2 to 40 times
() # DEFINE Capture group 1
.* # Any char, 0 or more times
){3} # 'Word Group' end, do 3 times
Or, by using a conditional
^(?=.*[##$%^&+=])(?=.*\d)(?:(?(1)\s).*([a-zA-Z0-9]{2,40}).*){3}
^ ^
---------------------------------------
^ # String start
(?=.*[##$%^&+=]) # Assert 1 special char
(?=.*\d) # Assert 1 digit
(?: # Special 'Word Group'
(?(1)\s) # Conditional, require a whitespace if capture group 1 captured anything
.* # Any char, 0 or more times
([a-zA-Z0-9]{2,40}) # Capture group 1, Alpha/num char, 2 to 40 times
.* # Any char, 0 or more times
){3} # 'Word Group' end, do 3 times