Regular expression to allow only negative number - regex

This sounds like it would be a fairly common issue, but I've searched a lot and can't find anything that works. I'm using the jquery validate plug-in to validate form input. There's a field which needs to accept only negative numbers (can be whole integers or decimals but must be less than zero).
I've tried doing something like this:
$.validator.addClassRules("negativeNumber", { range: [-1000000000, 0] });
...which works okay, but the validation error is horrible ("Please enter a number between -1000000000 and 0") - I'd like it to just say "Please enter a negative number".
Could anyone point me in the direction of a regex that only allows negative numbers?
Many thanks folks...

Instead of a regex, you can add a custom validation method, which I believe is easier to read.
$.validator.addMethod('negativeNumber',
function (value) {
return Number(value) < 0;
}, 'Enter a negative number');

I would think \-\d*(\.?\d+) would do it.
\- matches a minus
\d* matches zero or more digits (to account for things like -.5)
\.? matches a decimal point if it's there
\d* matches zero or more digits

This will match anything less than 0 \-\d*(\.\d+)?
Including -.00001, -100000, and -1

This would be so much easier with a custom validation method:
jQuery.validator.addMethod('negativeNumber', function(value, element) {
return this.optional(element) || (+value < 0);
}, 'Please enter a negative number');
That is much nicer (and probably quicker) than regex, and let's the browser parse the number for you, rather than doing it yourself with regex.
Or, of course, use the max method, although the message there isn't quite as nice.

Related

Possible to limit to scope/range of a lookahead

We can check to see if a digit is in a password, for example, by doing something like:
(?=.*\d)
Or if there's a digit and lowercase with:
(?=.*\d)(?=.*[a-z])
This will basically go on "until the end" to check whether there's a letter in the string.
However, I was wondering if it's possible in some sort of generic way to limit the scope of a lookahead. Here's a basic example which I'm hoping will demonstrate the point:
start_of_string;
middle_of_string;
end_of_string;
I want to use a single regular expression to match against start_of_string + middle_of_string + end_of_string.
Is it possible to use a lookahead/lookbehind in the middle_of_string section WITHOUT KNOWING WHAT COMES BEFORE OR AFTER IT? That is, not knowing the size or contents of the preceding/succeeding string component. And limit the scope of the lookahead to only what is contained in that portion of the string?
Let's take one example:
start_of_string = 'start'
middle_of_string = '123'
end_of_string = 'ABC'
Would it be possible to check the contents of each part but limit it's scope like this?
string = 'start123ABC'
# Check to make sure the first part has a letter, the second part has a number and the third part has a capital
((?=.*[a-z]).*) # limit scope to the first part only!!
((?=.*[0-9]).*) # limit scope to only the second part.
((?=.*[A-Z]).*) # limit scope to only the last part.
In other words, can lookaheads/lookbehinds be "chained" with other components of a regex without it screwing up the entire regex?
UPDATE:
Here would be an example, hopefully this is more helpful to the question:
START_OF_STRING = 'abc'
Does 'x' exist in it? (?=.*x) ==> False
END_OF_STRING = 'cdxoy'
Does 'y' exist in it? (?=.*y) ==> True
FULL_STRING = START_OF_STRING + END_OF_STRING
'abcdxoy'
Is it possible to chain the two regexes together in any sort of way to only wok on its 'substring' component?
For example, now (?=.*x) in the first part of the string would return True, but it should not.
`((?=.*x)(?=.*y)).*`
I think the short answer to this is "No, it's not possible.", but am looking to hear from someone who understands this to tell why it is or isn't.
In .NET and javascript you could use a positive lookahead at the start of your string component and a negative lookbehind at the end of it to "constrain" the match. Example:
.*(?=.*arrow)(?<middle>.*)(?<=.*arrow).*
helloarrowxyz
{'middle': 'arrow'}
If in pcre, python, or other you would need to either have a fixed width lookahead to constraint it from going too far forward, such as what Wiktor Stribiżew says above:
.*(?=.{0,5}arrow)(?<middle>.{0,5}).*
Otherwise, it wouldn't be possible to do without either a fixed-width lookahead or a variable width look-behind.

Regex: "password must have at least 3 of the 4 of the following"

I'm a Regex newbie, and so far have only used it for simple things, like "must be a number or letter". Now I have to do something a bit more complex.
I need to use it to validate a password, which must be 8-16 characters, free of control/non-printing/non-ASCII characters, and must have at least three of the following:
one capital letter
one lowercase letter
one number 0-9
one symbol character ($, %, &, etc.)
I'm thinking what I have to do is write something like "one capital letter, lowercase letter and number, OR one capital letter, lowercase letter and one symbol, OR one capital letter, one number or one symbol, OR...." to cover all possible "3 out of 4" combinations, but that seems excessive. Is there a simpler solution?
The correct way to do this is to check all of the five conditions separately. However, I assume there is a reason you want a regex, here you go:
/^((?=.*[A-Z])(?=.*[a-z])(?=.*\d)|(?=.*[a-z])(?=.*\d)(?=.*[\$\%\&])|(?=.*[A-Z])(?=.*\d)(?=.*[\$\%\&])|(?=.*[A-Z])(?=.*[a-z])(?=.*[\$\%\&])).{8,16}$/
Explanation:
We want to match the whole thing, hence we surround it with ^$
.{n,m} matches between n and m characters (8 and 16 in our case).
The general way you can check if a string contains something, without actually matching it is by using positive lookahead (?=.*X), where X is the thing you want to check. For example, if you want to make sure the string contains a lowercase letter you can do (?=.*[a-z]).
If you want to check if a string contains X, Y and Z, but without actually matching them, you can use the previous recipe by appending the three lookaheads (?=.*X)(?=.*Y)(?=.*Z)
We use the above to match three of the four things mentioned. We go through all possible combinations with |(or) - cCD|cDS|CDS|CcS (c = lowercase letter, C = capital letter, D = digit, S = special)
See it in action
The best way to do this is by checking each condition separately. Performance will suffer if you try to fit all conditional criteria into one expression (see the accepted answer). I also highly recommend against limiting the length of the password to 16 chars — this is extremely insecure for modern standards. Try something more like 64 chars, or even better, 128 — assuming your hashing architecture can handle the load.
You also didn't specify a language, but this is one way to do it in JavaScript:
var pws = [
"%5abCdefg",
"&5ab",
"%5abCdef",
"5Bcdwefg",
"BCADLKJSDSDFlk"
];
function pwCheck(pw) {
var criteria = 0;
if (pw.toUpperCase() != pw) {
// has lower case letters
criteria++;
}
if (pw.toLowerCase() != pw) {
// has upper case letters
criteria++;
}
if (/^[a-zA-Z0-9]*$/.test(pw) === false) {
// has special characters
criteria++;
}
if (/\d/.test(pw) === true) {
// has numbers
criteria++;
}
// returns true if 3 or more criteria was met and length is appropriate
return (criteria >= 3 && pw.length >= 8 && pw.length <= 16);
}
pws.forEach(function(pw) {
console.log(pw + ": " + pwCheck(pw).toString());
});
Not sure if its a iOS thing, the regex with "d" for digits [0-9] wasn't working as expected, example String that had issues = "AAAAAA1$"
The fix below works fine in Objective-C and Swift 3
^((?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])|(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[^a-zA-Z0-9])|(?=.*?[A-Z])(?=.*?[0-9])(?=.*?[^a-zA-Z0-9])|(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^a-zA-Z0-9])).{8,16}$

how to express that 1st number must less than 2nd number in regular expression /^\d+-\d+$/

I have to validate a string that two natural number joined by a hyphen
and the first number must less than second number. please tell me is this
possible, thank you.
pattern:
/^\d+-\d+$/
it it possible to do this?
1-2 OK
2-1 NG
Try this way. if use php:
function valid_num($a){
$a=explode("-",$a);
if($a[0]<$a[1]) return true;
else return false;
}
valid_num("1-2");// true
valid_num("2-1");// false
Sadly, regex does not do mathematical computations. You will have to find another option.

Regex pattern for validating password

I am working with a small issue, but I don't know how to solve it clearly. I have to validate a generated password, with some constraints:
password length: [8, 24]
password contains
at least 1 lower case character
at least 1 upper case character
at least 1 digit
at least 1 special character (printable based on ASCII code)
I've used Regex pattern, but it didn't work correctly with both cases: valid and invalid.
The first RegEx pattern:
def pattern = /(=?.{8,24})((:?[a-z]+)(:?[0-9]+)(:?[A-Z]+)(:?\W+))/
can check all invalid passwords but not for the valid one.
The second RegEx pattern:
def pattern = /(=?.{8,24})((:?[a-z]*)(:?[0-9]*)(:?[A-Z]*)(:?\W*))/
can check all valid passwords but not for the invalid one.
I am new to Groovy, so I don't know how to create the correct RegEx pattern to solve this.
Could you please help me?
Regex is not a solution to everything, and trying to come up with a single regex for a given problem is often wasting brain cycles. Just separate it out into multiple tests, for example (this Perl-like pseudo code, but you should be able to transform that to the language you are using):
sub valid_pw
{
return false if (length($_) < 8 || length($_) > 24);
# don't use [a-z], it makes for nasty surprises in e.g. fi_FI
return false if (!/[[:lower:]]/);
return false if (!/[[:upper:]]/);
return false if (!/[[:digit:]]/);
return false if (!/[[:print:]]/);
return true;
}
Why do you need a single regex for this? (also why are you placing a maximum length on the password, which is another discussion)
/^.{8,24}$/
/[a-z]/
/[A-Z]/
/\d/
/[^\d\w]/
I guess you could combine them using lookaheads (say /(?=.*[a-z])(?=.*[A-Z])...), but if you do it's probably a really good idea to comment it heavily.

Optional characters in a regex

The task is pretty simple, but I've not been able to come up with a good solution yet: a string can contain numbers, dashes and pluses, or only numbers.
^[0-9+-]+$
does most of what I need, except when a user enters garbage like "+-+--+"
I've not had luck with regular lookahead, since the dashes and pluses could potentially be anywhere in the string.
Valid strings:
234654
24-3+-2
-234
25485+
Invalid:
++--+
How about this:
([+-]?\d[+-]?)+
which means "one or more digits, each of which can be preceded or followed by an optional plus or minus".
Here's a Python test script:
import re
TESTS = "234654 24-3+-2 -234 25485+ ++--+".split()
for test in TESTS:
print test, ":", re.match(r'([+-]?\d[+-]?)+', test) is not None
which prints this:
234654 : True
24-3+-2 : True
-234 : True
25485+ : True
++--+ : False
How about:
^[0-9+-]*[0-9][0-9+-]*$
This ensures that there is at least one digit somewhere in the string. (It looks like it might have a lot of backtracking, though. But on the other hand it doesn't have a + or * wrapped inside another + or *, which I don't like either.)
^([+-]*[0-9]+[+-]*)+$
Another solution using a positive look behind assertion ensuring there is at leat one number.
^[0-9+-]+$(?<=[0-9][+-]*)
Or using a positive look ahead assertion.
(?=[+-]*[0-9])^[0-9+-]+
I like the
^(?=.*\d)[\d+-]+$
solution, myself. It says exactly what you need without requiring any head-scratching.
I'd do it like this:
^[-+]*\d[\d+-]*$
Fast is good!