I am working on a Rails 3 application that needs to validate the password based on the following criteria: must be at least 6 characters and include one number and one letter.
Here is my Regex:
validates :password, :format => {:with => /^[([a-z]|[A-Z])0-9_-]{6,40}$/, message: "must be at least 6 characters and include one number and one letter."}
Right now if I put in a password of (for ex: dogfood) it will pass. But what I need it to do is to pass the criteria above.
I am not all that great at regex, so any and all help is greatly appreciated!
Use lookahead assertions:
/^(?=.*[a-zA-Z])(?=.*[0-9]).{6,}$/
| | |
| | |
| | Ensure there are at least 6 characters.
| |
| Look ahead for an arbitrary string followed by a number.
|
Look ahead for an arbitrary string followed by a letter.
Technically in this case you don't need the anchors, but it's good habit to use them.
Related
I'm a regex newbie and I've got a valid regex for SSNs:
/^(\d{3}(\s|-)?\d{2}(\s|-)?\d{4})|[\d{9}]*$/
But I now need to expand it to accept either an SSN or another alphanumeric ID of 7 characters, like this:
/^[a-zA-Z0-9]{7}$/
I thought it'd be as simple as grouping the SSN and adding an OR | but my tests are still failing. This is what I've got now:
/^((\d{3}(\s|-)?\d{2}(\s|-)?\d{4})|[\d{9}])|[a-zA-Z0-9]{7}$/
What am I doing wrong? And is there a more elegant way to say either SSN or my other ID?
Thanks for any helpful tips.
Valid SSNs:
123-45-6789
123456789
123 45 6789
Valid ID: aCe8999
I have modified your first regex also a bit, below is demo program. This is as per my understanding of the problem. Let me know if any modification is needed.
my #ids = (
'123-45-6789',
'123456789',
'123 45 6789',
'1234567893434', # invalid
'123456789wwsd', # invalid
'aCe8999',
'aCe8999asa' # invalid
);
for (#ids) {
say "match = $&" if $_ =~ /^ (?:\d{3} ([ \-])? \d{2} \1? \d{4})$ | ^[a-zA-Z0-9]{7}$/x ;
}
Output:
match = 123-45-6789
match = 123456789
match = 123 45 6789
match = aCe8999
Your first regex got some problems. The important thing about it is that it accepts {{{{}}}}} which means you have built a wrong character class. Also it matches 123-45 6789 (notice the mixture of space and dash).
To mean OR in regular expressions you need to use pipe | and remember that each symbol belongs to the side that it resides. So for example ^1|2$ checks for strings beginning with 1 or ending with 2 not only two individual input strings 1 and 2.
To apply the exact match you need to do ^1$|^2$ or ^(1|2)$.
With the second regex ^[a-zA-Z0-9]{7}$ you are not saying alphanumeric ID of 7 characters but you are saying numeric, alphabetic or alphanumeric. So it matches 1234567 too. If this is not a problem, the following regex is the solution by eliminating the said issues:
^\d{3}([ -]?)\d\d\1\d{4}$|^[a-zA-Z0-9]{7}$
I need to create a regex to validate a password and then create a DFA with it.
The sets are:
a = {a,...,z}
| A = {A,...,Z}
| d = {0,...,9}
The criteria are:
Must begin with a letter (doesn't matter if upper or lower case).
| Must contain at least 1 upper case.
| Must contain at least 1 lower case.
| Must contain at least 1 number.
So far, I've come with the following Regex:
(aa\*(AA\*a\*dd\*|dd\*a\*AA\*)|AA\*(aa\*A\*dd\*|dd\*A\*aa\*))(a|A|d)\*
Is it correct?
The inner parts of your expression are slightly wrong. For example, with AA*a*dd*, you trying to check the case where it begins with 'a' and then 'A' occurs before 'd', but this does not match "aAaAd". Here is a correct version:
(aa*(d(a|d)*A|A(a|A)*d)|AA*(d(A|d)*a|a(A|a)*d))(a|A|d)*
The DFA you should do as an exercise. It should have 7 states including start and end. Think about establishing one state for each combination of characters that you have left to match.
I'm trying to write a regex that checks if string contains 6 or more signs including 1 or more special sign [^0-9a-zA-Z\s] and 1 or more [0-9a-zA-Z].
Spent like 2h and not getting any closer :/
maybe this is of some help:
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).{6,13}$
Password expresion that requires one lower case letter, one upper case letter, one digit, 6-13 length, and no spaces.
Matches:
1agdH*$# | 1agdC*$# | 1agdB*$#
Non-Matches:
wyrn%#*&$# f | mbndkfh782 | BNfhjdhfjd&*)%#$)
This is based on the Regex Lib entry here
Taking the style of Hasson's answer . . .
grep -P '^(?=.*[^a-zA-Z0-9\s])(?=.*[a-zA-Z0-9])(?!.*\s).{6}'
6 or more chars (regexp not ended with $)
1 or more special char (?=.*[^0-9a-zA-Z\s])
1 or more (?=.*[0-9a-zA-Z])
no whitespace (?!.*\s)
Some test data, NO match:
password
pa5sword
pa5sWord
pa5sWord
password
test
1agdA
1agd
wyrn%#*&$# f
mbndkfh782
t1*$
Some test data, YES match:
pa5*Word
pa5*Word
pa5*Word1
pa5*Wor
1agdA*
1agdA*$
1agdA*$#
1agdA*$#1
1agdA*$#12
1agdA*$#123
1agdA*$#a
1agdA*$#ab
1agdA*$#abc
1agdA*$#abcd
BNfhjdhfjd&*)%#$)
I am looking at regexes to validate and parse well-known text, which is a format used to transfer spatial data and looks like:
POLYGON((51.124 -3.973, 51.1 -3.012, ....))
or
MULTIPOLYGON(((POLYGON((51.124 -3.973, 51.1 -3.012, ....)),POLYGON((50.14 -13.973, 51.1 -13.012, ....))
among other variations.
There is a good answer here: Parsing a WKT-file which uses the regex:
\d+(?:\.\d*)?
From other places I have also seen
\d*\.\d+|\d+
and
(\d*\.)?\d+
These all seem to do the same thing, but it got me wondering about the relative workings of these 3 regexes, and if there are any performance issues or subtleties under the hood to be aware of.
To be clear, I am aware that there are libraries for parsing WKT in various languages. My question is purely about the relative behavior of number extracting regexes.
It depends what number formats you need to allow, example:
format 1: 22
format 2: 22.2
format 3: .2
format 4: 2.
the 1st pattern \d+(?:\.\d*)? matches 1,2,4
the 2nd pattern \d*\.\d+|\d+ matches 1,2,3
the 3rd pattern (\d*\.)?\d+ matches 1,2,3 (and have an uneeded capturing group)
Note: pattern 2 and 3 are slower to succeed than the first if the number is an integer, because they must match all digits until the dot, backtrack to the start and retry the same digits one more time. (see the schema below)
str | pattern | state
-----+----------------+-----------------------------
123 | \d*\.\d+|\d+ | START
123 | \d*\.\d+|\d+ | OK
123 | \d*\.\d+|\d+ | OK
123 | \d*\.\d+|\d+ | OK
123 | \d*\.\d+|\d+ | FAIL => backtrack
123 | \d*\.\d+|\d+ | FAIL => backtrack
123 | \d*\.\d+|\d+ | FAIL => backtrack
123 | \d*\.\d+|\d+ | go to the next alternative
123 | \d*\.\d+|\d+ | OK
123 | \d*\.\d+|\d+ | OK
123 | \d*\.\d+|\d+ | OK => SUCCESS
if you want to match the four cases, you can use:
\.\d+|\d+(?:\.\d*)?
(+) if the number doesn't begin with a dot, the first alternative fails immediatly and the second alternative will match all other cases. The backtracking is limited to the minimum.
(-) if you have few numbers that start with a dot the first alternative will be tested and will fail each times. However, the first alternative fails quickly.(in other words, for the same reason). In this case, it is better to use \d+(?:\.\d*)?|\.\d+
Obviously, if you want to support negative values you need to add -?:
-?(?:\.\d+|\d+(?:\.\d*)?)
I googled a lot, but I'm stuck.
There is a cool thing in HTML5, required patterns. It's great for emails / phones / dates validation. I use it in my small project for checking numbers. What I need is a pattern for:
YYYY.ordernumber
Order number may be any number from 1 to 1000000.
I tried to modify some YYYY.MM patterns for my case, but with no luck. What ever I type in does not pass the validation.
Can anyone please help?
UPDATE: Added a lookahead to ensure 'ordernumber' is > 0 (thanks to M42's remark in comments).
You can use those two attributes with your <input>:
pattern="^[0-9]{4}\.(?!0+$)([0-9]{1,6}|1000000)$"
required
E.g.
<input type="text" placeHolder="YYYY.ordernumber" title="YYYY.ordernumber"
pattern="^[0-9]{4}\.(?!0+$)([0-9]{1,6}|1000000)$" required />
See, also, this short demo.
Short explanation of the regex:
^[0-9]{4}\.(?!0+$)([0-9]{1,6}|1000000)$ _____________
^\______/\/\_____/ \________/\______/ ^___|match the end|
| | | |_(*2) |_ |_____ |of the string|
_______| | |____ | |
_________|__ _______|_____ _|______ _|________ _|______
|match the | |match exactly| |match a | |match 1 to| |or match|
|beggining of| |4 digits | |dot (*1)| |6 digits | |1000000 |
|the string |
(*1): '.' is a special character in regex, so it has to be escaped ('.').
(*2): This is a negative lookahead which does consume any characters, but looks ahead and makes sure that the rest of the string in not consisted of zeros only.
Just for the sake of completeness:
I must point out the fact that [0-9] matches only digits 0-9. If you need to also match other digit characters, such as for example Eastern Arabic numerals (٠١٢٣٤٥٦٧٨٩), you can use \d instead.