I'm using this to (try) to validate a 'strong' password in ColdFusion 7.
if ( REFind("^(?=.*[A-Z])(?=.*[!###$&*])(?=.*[0-9])(?=.*[a-z]).{6}$", myPassword, 1) EQ 0 )
However, it is failing. Can someone point out my error?
The criteria I think I'm testing is:
1 upper
1 lower
1 number
1 special char
6 digit min
Footnotes for non-CF people:
the double hash is to escape the CF hash;
ColdFusion uses Jakarta ORO 2.0.6 as its regex engine
Ok, well the set of criteria you're trying to test on are bad.
For example, Pa$5word meets the criteria but is a bad choice, whilst my name |z NOT Fr£d is much stronger but fails (no numbers; different symbols).
Ideally you should look for and existing password strength checker (although I've no idea if there are any existing/good ones out there).
Anyhow, for a simple solution to what you've asked, that spells out exactly what is being checked, just do:
<cfif NOT
( len(myPassword) GTE 6
AND refind('[A-Z]',myPassword)
AND refind('[a-z]',myPassword)
AND refind('[0-9]',myPassword)
AND refind('[!###$&*]',myPassword)
)>
There is no need/benefit to smushing it all into a single regex.
One reason why it might be failing is your business rule is "at least six characters", but your regex enforces exactly six characters.
Also: it'd be helpful it you stated which conditions it fails on. My superficial testing suggests you're fine except for the caveat I mention above. If you could finetune your question to point out what non-superficial testing that I'm not thinking about is failing, that'd be helpful.
In the real world, I'd also expect what punctuation characters you consider valid, too. Your list is a bit short. But that's nowt to do with you current problem.
Try this.
^(?=.[A-Z])(?=.[!###\$&])(?=.[0-9])(?=.*[a-z]).{6,}$
Add comma after six since you want to allow more than 6 characters and $ must be escaped with \$
Update
Try below, ^ and $ removed from above one
(?=.[A-Z])(?=.[!###$&])(?=.[0-9])(?=.*[a-z]).{6,}
fwiw to separate out the different character failures:
<cfscript> raRe=[["[a-z]","lowercase"],["[A-Z]","uppercase"],["[\W]","non-alphanumeric"],["[\d]","numeric"]];</cfscript>
<cfoutput>
<cfloop from=1 to=4 index="idxRe">
#idxRe#: refind(raRe[idxRe][1], myPassword):<b>#refind(raRe[idxRe][1], myPassword)#</b> myPassword:<b>#myPassword#</b>; re:<b>#raRe[idxRe][1]#</b>; <br />
<cfif refind(raRe[idxRe][1], myPassword) eq 0><b>Your password must include at least one #raRe[idxRe][2]# character</b><br /></cfif>
</cfloop>
</cfoutput>
And of course if >=6 is also required:
<cfif Len(myPassword) lte 6><b>Your password must be at least 6 characters long</b></cfif>
Related
in order to validate a simple PIN, which can include leading 0, I wrote the following very-simple regexp:
^[0-9][0-9][0-9][0-9][0-9][0-9]$
This one works as expected on the different online regexp tools I tried, however, it doesn't work in Angular validator, because of the leading 0 which is not counted as a digit:
PIN = new FormControl('', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(6),
Validators.pattern('^([0-9][0-9][0-9][0-9][0-9][0-9])$'),
]);
formPINGroup = this.formBuilder.group({
PIN: this.PIN,
});
I can't figure this out despite the different forums I browsed, people are always looking for the opposite.
If an Angular expert sees this post, his help is welcomed!
In the meantime, take care!
EDIT:
I have created a Stackblitz if you wanna try something:
https://stackblitz.com/edit/angular-zzsjn1
here three results:
the first is not OK because of the leading 0
second is ok because I added number 6, at the end
the last one is wrong, obviously.
The problem is an HTML5 input element. Try changing type="number" to type="tel" in hello-component.ts (from your link). With it you can technically still enter some non-numeric characters but only your pattern of 6 digits (with or without leading zeroes) will validate. See also
this thread
I have a validation rule checking for 10 digit US phone numbers, 11 Digit US and Canadian phone numbers and international phone numbers beginning with a + where the country code did not begin with a 1, they want dashes and spaces allowed. my validation rule seems to be working except for allowing spaces.
AND(
NOT(ISBLANK( Physical_Service_After_Hours_Phone__c)),
NOT(REGEX( Physical_Service_After_Hours_Phone__c, "(\\d){10}")),
NOT(REGEX(Physical_Service_After_Hours_Phone__c,"^((\\1)?\\d{11})?$")),
NOT(
AND(
OR(
LEN(Physical_Service_Scheduling_Phone__c )=0,
REGEX(Physical_Service_After_Hours_Phone__c, "^(\\+)([2-9])[0-9\\-\\s]+")
)
)
)
)
I tested your validation function as written in a Sandbox. In testing, the validation allows any value as the after hours phone, as long as the scheduling phone is blank. If the scheduling phone is not blank, it gives an error when I put spaces in the other field. I couldn't immediately see why when reviewing your code. Indentation helps me understand complicated functions, so let's start by adding some indentation so we can better see what the function is doing.
AND(
NOT(ISBLANK(Physical_Service_After_Hours_Phone__c)),
NOT(REGEX(Physical_Service_After_Hours_Phone__c, "(\\d){10}")),
NOT(REGEX(Physical_Service_After_Hours_Phone__c, "^((\\1)?\\d{11})?$")),
NOT(
AND(
OR(
LEN(Physical_Service_Scheduling_Phone__c)=0,
REGEX(Physical_Service_After_Hours_Phone__c, "^(\\+)([2-9])[0-9\\-\\s]+")
)
)
)
)
Now we see there are four main criteria, with the fourth being more complicated than the others. Let's see how a sample after hours number of 555 555 1212 makes its way through this function, assuming the scheduling number is not blank.
NOT(ISBLANK(Physical_Service_After_Hours_Phone__c))
The after hours number is not blank, so this evaluates to NOT(False) which is True.
NOT(REGEX(Physical_Service_After_Hours_Phone__c, "(\\d){10}"))
If we omitted spaces, this would match the regexp; but the regexp doesn't allow spaces, so this evaluates as NOT(False) which is True. If you want to allow spaces, tell the pattern matcher where they can be. If the rule is intended to cover only North America numbers, we groups digits as 3-3-4. This would work: "\\d{3}[ -]?\\d{3}[ -]?\\d{4}". Note that this precludes adding extension numbers and also allows haphazard spacing (555555 5555, 555-555 5555, and 555-5555555 would all be acceptable), which may or may not meet your requirements. Continuing to the next criterion:
NOT(REGEX(Physical_Service_After_Hours_Phone__c, "^((\\1)?\\d{11})?$"))
The number does not begin with 1 as required by this regexp, so this does not match and evaluates to NOT(False) which is True. This regexp also does not allow spaces and requires 11 digits following a 1, which is not likely what you intended. There is no need to escape 1 with slashes. You could combine this with the above into a single regexp by prefixing it with (1[ -]?)?, making it optional to start with 1 but allow a space or dash if you do.
This brings us to the fourth criterion, which is a bit more complicated:
NOT(
AND(
OR(
LEN(Physical_Service_Scheduling_Phone__c )=0,
REGEX(Physical_Service_After_Hours_Phone__c, "^(\\+)([2-9])[0-9\\-\\s]+")
)
)
)
If we assume the length of the scheduling phone is not 0 (i.e., we put something there), the first expression evaluates to False. And because the after hours number does not begin with a plus sign, it does not match the regexp, which also evaluates to False. We then end up with NOT(AND(OR(False, False))), which is True. Incidentally, you can remove the AND() function, as it does not do anything useful.
With all four criteria solved, we now have AND(True, True, True, True), which is True, thus signifying an error condition. While I have explained above which regexps need to be rewritten and how, in examining the fourth criteria, you should see another problem: As written, I don't see a way to fail when the scheduling number is blank. This is because when the scheduling number is blank, the fourth criterion always evaluates to False, and thus not an error, regardless of what is in the other field.
I would advise to do what I have done above: Break your problem down into smaller pieces and solve one at a time. You can use multiple validation rules to check this. For example:
AND(
LEFT(Physical_Service_After_Hours_Phone__c, 1) = "+",
NOT(REGEXP(Physical_Service_After_Hours_Phone__c, "^\\+([2-9]|8[\\-\\s])[0-9\\-\\s]+")
)
This function checks the first character; if it is a +, it matches the first expression. Then, if it fails the regexp for international numbers, it also matches the second expression and produces an error. On the other hand, if the first character is not a +, it will not match the first expression and continue to process other validation functions. (I also updated your regexp for international numbers to compensate for the fact that Russia has a single digit country code, leaving open the possibility that a user might follow it with a space or dash, per your original requirements.)
Alternatively, you could write a regexp to encompass both North America and international style numbers, but at the cost of legibility.
I want to check my form field's value whether it's numeric with two decimal and do the validation accordingly. It should accept numeric with two decimals ex: 2.33 else it should throw error like 2.987 it should not accept more than two decimal. Can anyone help me with this?
I have tried following:
<cfif NOT isValid(#NumberFormat( 7.4, ",.00" )#, dataValue)>
Regular expressions are a nice way to validate. Have a look at which option you could use here:
<cfif not reFind("^[0-9]+\.[0-9]{2}$", dataValue)>
<cfthrow type="IllegalArgumentException" message="You may input a decimal value with two decimal places only!">
</cfif>
^ = value has to start with the upcoming pattern
[0-9]+ = match digits from 0 to 9, one digit or more
\. = a dot (literally), the backslash is an escape symbol since . has a different effect
[0-9]{2} = match digits from 0 to 9, exactly two digits
$ = value has to end with the previous pattern
If you want to accept dot and comma as decimal separator, you can change \. to [,.].
If you want to accept one or two decimal spaces, you can change [0-9]{2} to [0-9]{1,2}.
If you don't require decimal places at all, but when they are present, they have to have two decimal places:
<cfif not reFind("^[0-9]+(\.[0-9]{2})?$", dataValue)>
<cfthrow type="IllegalArgumentException" message="You may input a decimal value without decimal places or with exactly two decimal places only!">
</cfif>
(\.[0-9]{2})? = the parenthesis group the pattern and the question mark marks it as "may match once" or "may not match at all".
Note: [0-9] is equivalent to \d. I just prefer to actually see the digits.
I don't like using cfinput but in the interest of time:
<cfinput type="text" name="name" mask="9.99"/>
You can use isValid() along with a regular expression to validate this:
<cfset input = "7.44">
<cfif isValid( "regex", input, "^\d+\.\d{2}$" )>
<!--- Valid input handler --->
<cfelse>
<!--- Invalid input handler --->
</cfif>
Here is a GIST.
Note:- Not related to your question but you don't need additional hash in the code that you have tried. You can check more here.
I have written a VIN validation RegEx based on the http://en.wikipedia.org/wiki/Vehicle_identification_number but then when I try to run some tests it is not accepting some valid VIN Numbers.
My RegEx:
^[A-HJ-NPR-Za-hj-npr-z\\d]{8}[\\dX][A-HJ-NPR-Za-hj-npr-z\\d]{2}\\d{6}$
VIN Number Not Working:
1ftfw1et4bfc45903
WP0ZZZ99ZTS392124
VIN Numbers Working:
19uya31581l000000
1hwa31aa5ae006086
(I think the problem occurs with the numbers at the end, Wikipedia made it sound like it would end with only 6 numbers and the one that is not working but is a valid number only ends with 5)
Any Help Correcting this issue would be greatly appreciated!
I can't help you with a perfect regex for VIN numbers -- but I can explain why this one is failing in your example of 1ftfw1et4bfc45903:
^[A-HJ-NPR-Za-hj-npr-z\d]{8}[\dX][A-HJ-NPR-Za-hj-npr-z\d]{2}\d{6}$
Explanation:
^[A-HJ-NPR-Za-hj-npr-z\d]{8}
This allows for 8 characters, composed of any digits and any letters except I, O, and Q; it properly finds the first 8 characters:
1ftfw1et
[\dX]
This allows for 1 character, either a digit or a capital X; it properly finds the next character:
4
[A-HJ-NPR-Za-hj-npr-z\d]{2}
This allows for 2 characters, composed of any digits and any letters except I, O, and Q; it properly finds the next 2 characters:
bf
\d{6}$
This allows for exactly 6 digits, and is the reason the regex fails; because the final 6 characters are not all digits:
c45903
Dan is correct - VINs have a checksum. You can't utilize that in regex, so the best you can do with regex is casting too wide of a net. By that I mean that your regex will accept all valid VINs, and also around a trillion (rough estimate) non-VIN 17-character strings.
If you are working in a language with named capture groups, you can extract that data as well.
So, if your goal is:
Only to not reject valid VINs (letting in invalid ones is ok) then use Fransisco's answer, [A-HJ-NPR-Z0-9]{17}.
Not reject valid VINs, and grab info like model year, plant code, etc, then use this (note, you must use a language that can support named capture groups - off the top of my head: Perl, Python, Elixir, almost certainly others but not JS): /^(?<wmi>[A-HJ-NPR-Z\d]{3})(?<vds>[A-HJ-NPR-Z\d]{5})(?<check>[\dX])(?<vis>(?<year>[A-HJ-NPR-Z\d])(?<plant>[A-HJ-NPR-Z\d])(?<seq>[A-HJ-NPR-Z\d]{6}))$/ where the names are defined at the end of this answer.
Not reject valid VINs, and prevent some but not all invalid VINs, you can get specific like Pedro does.
Only accept valid VINs: you need to write code (just kidding, GitHub exists).
Capture group name key:
wmi - World manufacturer identifier
vds - Vehicle descriptor section
check - Check digit
vis - Vehicle identifier section
year - Model year
plant - Plant code
seq - Production sequence number
This regular expression is working fine for validating US VINs, including the one you described:
[A-HJ-NPR-Z0-9]{17}
Remember to make it case insensitive with flag i
Source: https://github.com/rfink/angular-vin
VIN should have only A-Z, 0-9 characters, but not I, O, or Q
Last 6 characters of VIN should be a number
VIN should be 17 characters long
You didn't specify which language you're using but the following regex can be used to validate a US VIN with php:
/^(?:([A-HJ-NPR-Z]){3}|\d{3})(?1){2}\d{2}(?:(?1)|\d)(?:\d|X)(?:(?1)+\d+|\d+(?1)+)\d{6}$/i
I feel regex is not the ideal validation. VINs have a built in check digit. https://en.wikibooks.org/wiki/Vehicle_Identification_Numbers_(VIN_codes)/Check_digit or http://www.vsource.org/VFR-RVF_files/BVINcalc.htm
I suggest you build an algorithm using this. (Untested algorithm example)
This should work, it is from splunk search, so there are some additional exclusions**
(?i)(?<VIN>[A-Z0-9^IOQioq_]{11}\d{6})
The NHTSA website provides the method used to calculate the 9th character checksum, if you're interested. It also provides lots of other useful data, such as which characters are allowed in which position, or how to determine whether the 10th character, if alphabetic, refers to a model year up to 1999 or a model year from 2010.
NHTSA VIN eCFR
Hope that helps.
Please, use this regular expression. It is shorter and works with all VIN types
(?=.*\d|[A-Z])(?=.*[A-Z])[A-Z0-9]{17}
I changed above formula by new below formula
(?=.*\d|=.*[A-Z])(?=.*[A-Z])[A-Z0-9]{17}
This regular expression consider any letter but at leats one digit, max 17 characters
There's a long natural number that can be grouped to smaller numbers by the 0 (zero) delimiter.
Example: 4201100370880
This would divide to Group1: 42, Group2: 110, Group3: 370880
There are 3 groups, groups never start with 0 and are at least 1 char long. Also the last groups is "as is", meaning it's not terminated by a tailing 0.
This is what I came up with, but it only works for certain inputs (like 420110037880):
(\d+)0([1-9][0-9]{1,2})0([1-9]\d+)
This shows I'm attempting to declare the 2nd group's length to min2 max3, but I'm thinking the correct solution should not care about it. If the delimiter was non-numeric I could probably tackle it, but I'm stumped.
All right, factoring in comment information, try splitting on a regex (this may vary based on what language you're using - .split(/.../) in JavaScript, preg_split in PHP, etc.)
The regex you want to split on is: 0(?!0). This translates to "a zero that is not followed by a zero". I believe this will solve your splitting problem.
If your language allows a limit parameter (PHP does), set it to 3. If not, you will need to do something like this (JavaScript):
result = input.split(/0(?!0)/);
result = result.slice(0,2).concat(result.slice(2).join("0"));
The following one should suit your needs:
^(.*?)0(?!0)(.*?)0(?!0)(.*)$
Visualization by Debuggex
The following regex works:
(\d+?)0(?!0) with the g modifier
Demo: http://regex101.com/r/rS4dE5
For only three matches, you can do:
(\d+?)0(?!0)(\d+?)0(?!0)(.*)