I need a regular expression that helps me to accept both positive and negative numbers
I have used ^-?\d*(.\d+)?$ expression
validateNegativeNumber(e: any) {
let input = String.fromCharCode(e.charCode);
const reg = /^-?\d*(.\d+)?$/;
if (!reg.test(input)) {
e.preventDefault();
}
}
Expected result: 5, +5, -5, 0
Unexpected results: 1.5, -1.5, 5++++, ++5, ---5, 5--, 50--6
You missed checking for + sign. Also there is no need for capturing groups.
Use this:
^[+-]?\d+$
An optional + or - sign at the beginning
Followed by one or more digits till the end
Demo
You can use the pattern attribute of input tag in HTML, like below:
<input pattern="^[+-]?\d+$">
Explanation: pattern attribute is available, it is better use rather than calling a function that validates the input. That will be an extra work.
I hope it helps.
Use this, for accept positive or negative both number.
^-?[0-9]\d*(\.\d+)?$
^[+-]?\d+(?:\.\d+)?$
Explanation:
^ matches the beginning of the string (so "abc212" will not validate)
[+-]? the first allowed char che be + o - matching 0 or 1 occurrence (the ?). Note that if you don't want the + sign, you can just write -?, so the regex will validate matching 0 or 1 occurrence of - as first char
\d+ after that you can have any number of digits (at least one, because we user the +)
(?:\.\d+)? at the end we can have 0 or 1 occurrence (given by the ?) of a dot (\.) followed by any number of digits (\d+). Note that the ?: at the beginning of the group says that this is a "non-capturing group")
$ matches the ending of the string (so "231aaa" will not validate)
How about this one?
const reg = /^[+-]?\d*(\.\d+)?$/;
const valids = ['+5', '-5', '5', '-5', '-0.6', '.55', '555.124'];
const invalids = ['--5', '5+', '5-'];
console.log('testing for valids array');
valids.forEach(valid => {
console.log(reg.test(valid));
});
console.log('testing for invalids array');
invalids.forEach(invalid => {
console.log(reg.test(invalid));
});
Related
I want validate a money string with numbers max length 13 with 2 decimal. I have a comma as decimal separator and a period as a thousands separator.
I have this regex:
/^(\d{1}\.)?(\d+\.?)+(,\d{2})?$/
For sintax is valid but not for max length. What I need to add to this regex?
For example, these strings must be valid:
1.000.000.000.000
1.000.000.000.000,00
1
1,00
123,45
And these must be invalid:
10.000.000.000.000
10.000.000.000.000,00
10.000.000.000.000.000
10.000.000.000.000.000,00
Maybe try to assert position is not followed by 18 digits/dots using a negative lookahead:
^(?![\d.]{18})\d{1,3}(?:\.\d{3})*(?:,\d\d?)?$
See an online demo. Here is assumed you would also allow a single digit decimal.
^ - Open line anchor.
(?![\d.]{18}) - Negative lookahead to prevent 18 digits/dots ahead.
\d{1,3} - One-to-three digits.
(?:\.\d{3})* - A non-capture group of a literal dot followed by three digits with a 0+ multiplier.
(?:,\d\d?)? - Optional non-capture group of a comma followed by either 1 or two digits. Remove the question mark to make the 2nd decimal non-optional.
$ - End line anchor.
You may use this regex for validation:
^(?=[\d.]{1,17}(?:,\d{2})?$)\d{1,3}(?:\.\d{3})*(?:,\d{2})?$
RegEx Demo
RegEx Details:
^: Start
(?=[\d.]{1,17}(?:,\d{2})?$): Lookahead to match dot or digit 1 to 17 times followed by optional comma and 2 digits
\d{1,3}: Match 1 to 3 digits
(?:\.\d{3})*: Match . followed by 3 digits. Repeat this group 0 or more times
(?:,\d{2})?: Match optional , followed 2 decimal digits
$: End
90% of the time there is a better solution than using regex. It's probably best just to convert your strings into a real number then compare vs. your limit (ie 9999999999999.99).
// Pass a string
function convertStr(string) {
/*
Remove all '.'
Replace all ',' with '.'
*/
let numStr = string.split('.').join('').replaceAll(',', '.');
// Convert modified string into a real number
let realNum = parseFloat(numStr);
/*
if converted string is a real number...
round it to two decimal places and return it
Otherwise return false
*/
return !Number.isNaN(realNum) ? Math.round((realNum + Number.EPSILON) * 100) / 100 : false;
}
// Pass a string and the maxed number
function numLimit(string, limit) {
// Get the result of convertString()
let number = convertStr(string);
// if the result is equal to or less than limit...
if (number <= limit) {
return true;
} else {
return false;
}
}
const limit = 9999999999999.99;
const valid = ['1.000.000.000.000',
'1.000.000.000.000,00', '1', '1,00', '123,45'
];
const invalid = ['10.000.000.000.000', '10.000.000.000.000,00', '10.000.000.000.000.000', '10.000.000.000.000.000,00'];
let validResults = valid.map(str => numLimit(str, limit));
let invalidResults = invalid.map(str => numLimit(str, limit));
console.log('valid: ' + validResults);
console.log('invalid: ' + invalidResults);
I've being trying to generate a regex for this string:
case1: test-123456789 should get 56789
case2: test-1234-123456789 should get 56789
case3: test-12345 should fail or not giving anything
what I need is a way to get only the last 5 numbers from only 9 numbers
so far I did this:
case.match(/\d{5}$/)
it works for the first 2 cases but not for the last one
You may use
/\b\d{4}(\d{5})$/
See the regex demo. Get Group 1 value.
Details
\b - word boundary (to make sure the digit chunks are 9 digit long) - if your digit chunks at the end of the string can contain more, remove \b
\d{4} - four digits
(\d{5}) - Group 1: five digits
$ - end of string.
JS demo:
var strs = ['test-123456789','test-1234-123456789','test-12345'];
var rx = /\b\d{4}(\d{5})$/;
for (var s of strs) {
var m = s.match(rx);
if (m) {
console.log(s, "=>", m[1]);
} else {
console.log("Fail for ", s);
}
}
You can try this:
var test="test-123456789";
console.log((test.match(/[^\d]\d{4}(\d{5})$/)||{1: null/*default value if not found*/})[1]);
This way supports default value for when not found any matching (look at inserted comment inline above code.).
You can use a positive lookbehind (?<= ) to assert that your group of 5 digits is preceeded by a group of 4 digits without including them in the result.
/(?<=\d{4})\d{5}$/
var inputs = [
"test-123456789", // 56789
"test-1234-123456789", // 56789
"test-12345", //fail or not giving anything
]
var rgx = /(?<=\d{4})\d{5}$/
inputs.forEach(str => {
console.log(rgx.exec(str))
})
I'm trying to achieve this regular expression check. (1 integer, 3 digits)
Valid:
0.236
0.21
1.231
1.01
Invalid:
12.23
12321
0.21323
I would like to have only 1 digit follow by a decimal with only 0-3 decimal places.
Any help would be great. I have tried this:
^(([0-9]{1})?(?=\.)[0-9]{0,3})|([0-9]{1})$
but no lock.
Edit: I should have added that I'm using a JQuery plugin called inputmask. I would like for the inputmask to only accept my requirement.
To do this with jquery-inputmask, use this
<input id="example2" data-inputmask-regex="/^\d{1}\.\d{0,3}$/" />
And then in your JavaScript file, add this
$(document).ready(function(){
$("#example2").inputmask("Regex");
});
Here is the Regex breakdown
^ - Regex must start with this expression
\d{1} - Exactly 1 digit from 0 to 9
\. - Followed by a period. Important to note that periods must be escaped
\d{0,3} - Followed by 0 to 3 digits
$ - Regex must end with this expression
I tested for all of your examples.
I would like to have only 1 whole number follow by a decimal with only 0-3 decimal places.
By "1 whole number" I take it you mean one digit, as 12 is a single whole number. If so:
\d\.\d{0,3}
That matches a single digit followed by a . followed by zero to three digits. If you want to further assert that it matches the entire string, add anchors to either end:
^\d\.\d{0,3}$
Note that the rules you've given allow for 1., which seems like you may not want. If you don't, then we need to do a bit more work:
^\d(?:\.\d{1,3})?$
That says: One digit optionally followed by a . with 1-3 digits. It has the "whole string" anchors, remove them if you don't want them.
Live Example using that last one:
var input = document.querySelector("input");
var rex = [
/\d\.\d{0,3}/,
/^\d\.\d{0,3}$/,
/^\d(?:\.\d{1,3})?$/
];
input.oninput = input.onpaste = input.onkeypress = updateDisplay;
function updateDisplay() {
rex.forEach(function(r, index) {
var display = document.getElementById("r" + index);
if (!input.value) {
display.innerHTML = "--";
} else if (input.value.match(r)) {
display.innerHTML = "valid";
} else {
display.innerHTML = "INVALID";
}
});
}
<input type="text">
<p><code>/\d\.\d{0,3}/</code> says: <span id="r0"></span></p>
<p><code>/^\d\.\d{0,3}$/</code> says: <span id="r1"></span></p>
<p><code>/^\d(?:\.\d{1,3})?$/</code> says: <span id="r2"></span></p>
and so this must pass:
454555, 939999 , 019999 ,727663
its for a user entering 6 digit invoice numbers. it should fail if a number is 5 or 7 digit and not 6. so 1234567, 123456 should fail, as one set is more than 6 numbers.
So far I have :
[0-9]{6}(\s*,*,\s*[0-9]{6})*
which only draw back is that it accepts 7 or more digit numbers. cant figure out if its even possible at this point to do both, test for 6 digits separated by a comma and one or more space, and all the digits have to be only 6 digits and fail if one is not.
any help appreciated. regular expressions are not my forte.
thanks
Norman
You can write it using regex like the function below.
const isPassword = (password: string) => /^\d{6}$/gm.test(password);
And here is an example test file below.
test('should recognize a valid password', () => {
expect(isPassword('123456')).toBe(true);
expect(isPassword('000000')).toBe(true);
});
test('should recognize an invalid password', () => {
expect(isPassword('asdasda1234')).toBe(false);
expect(isPassword('1234567')).toBe(false);
expect(isPassword('a123456a')).toBe(false);
expect(isPassword('11.11.11')).toBe(false);
expect(isPassword('aaaaaa')).toBe(false);
expect(isPassword('eeeeee')).toBe(false);
expect(isPassword('......')).toBe(false);
expect(isPassword('werwerwerwr')).toBe(false);
});
In order to validate the full string you can use this regex.
^(\s*\d{6}\s*)(,\s*\d{6}\s*)*,?\s*$
It works with six digits only, and you have to enter at least one 6 digit number.
It also works if you have a trailing comma with whitespaces.
It's accepting more than six digit numbers because you're not anchoring the text, and for some odd reason you're optionally repeating the comma. Try something like this:
^[0-9]{6}(?:\s*,\s*[0-9]{6})*$
Also note that [0-9] is equivalent to \d, so this can be rewritten more concisely as:
^\d{6}(?:\s*,\s*\d{6})*$
Your regex does not match 7 digits in a row, but it also doesn't enforce that it matches the whole string. It just has to match some substring in the string, so it would also match each of these:
"1234512345612345612345"
"NaNaNaN 123456, 123456 BOOO!"
"!##$%^&*({123456})*&^%$##!"
Just add the start of string (^) and end of string ($) anchors to enforce that the whole string matches and it will work correctly:
^[0-9]{6}(\s*,*,\s*[0-9]{6})*$
Also note that ,*, could be shortened to ,+, and if you only want one comma in a row, just use ,, not ,* or ,+.
You can also replace [0-9] with \d:
^\d{6}(\s*,\s*\d{6})*$
Using only regex:
var commaSeparatedSixDigits = /^(?:\d{6}\s*,\s*)*\d{6}$/;
if (myInput.test(commaSeparatedSixDigits)) console.log( "Is good!" );
This says:
^ - Starting at the beginning of the string
(?:…)* - Find zero or more of the following:
\d{6} - six digits
\s* - maybe some whitespace
, - a literal comma
\s* - maybe some whitespace
\d{6} - Followed by six digits
$ - Followed by the end of the string
Alternatively:
var commaSeparatedSixDigits = /^\s*\d{6}(?:\s*,\s*\d{6})*\s*$/;
I leave it as an exercise to you to decipher what's different about this.
Using JavaScript + regex:
function isOnlyCommaSeparatedSixDigitNumbers( str ){
var parts = srt.split(/\s*,\s*/);
for (var i=parts.length;i--;){
// Ensure that each part is exactly six digit characters
if (! /^\d{6}$/.test(parts[i])) return false;
}
return true;
}
I see a lot of complication here. Sounds to me like what you want is pretty simple:
/^(\d{6},)*\d{6}$/
Then we account for whitespace:
/^\s*(\d{6}\s*,\s*)*\d{6}\s*$/
But as others have noted, this is actually quite simple in JavaScript without using regex:
function check(input) {
var parts = input.split(',');
for (var i = 0, n = parts.length; i < n; i++) {
if (isNaN(+parts[i].trim())) {
return false;
}
}
return true;
}
Tested in the Chrome JavaScript console.
There isn;t any real need for a regexp. Limit the input to only 6 characters, only accept numbers and ensure that the input has 6 digits (not show here). So you would need:
HTML
<input type='text' name='invoice' size='10' maxlength='6' value='' onkeypress='evNumersOnly(event);'>
JavaScript
<script>
function evNumbersOnly( evt ) {
//--- only accepts numbers
//--- this handles incompatabilities between browsers
var theEvent = evt || window.event;
//--- this handles incompatabilities between browsers
var key = theEvent.keyCode || theEvent.which;
//--- convert key number to a letter
key = String.fromCharCode( key );
var regex = /[0-9]/; // Allowable characters 0-9.+-,
if( !regex.test(key) ) {
theEvent.returnValue = false;
//--- this prevents the character from being displayed
if(theEvent.preventDefault) theEvent.preventDefault();
}
}
</script>
I have this code :
var tlTemp=new Array();
tlTemp.push("00 - 01:??:?? - TL 1");
tlTemp.push("00 - 12:??:?? - TL 2");
for(i=0; i<tlTemp.length; i++) {
var removedTL = tlTemp[i].match(/^(\d\d) - (\?\?|10|0\d):(\?\?|[0-5]\d):(\?\?|[0-5]\d) - (.*)/);
if(removedTL!=null) {
alert("ok");
}
else
{
alert("no");
return;
}
}
and I don't understand why first string print ok and the second (so similar) no. Why?
The appropriate part of the regexp that defines the different part of the string is:
(\?\?|10|0\d)
It matches:
??
10
0x where x is a digit
So 12 does not match.
Now, also there is TL 2 instead of TL 1 but in the regexp this is defined as:
(.*)
which matches everything so that is not causing the problem.
Because your regular expression explicitly excludes it.
This section:
/^(\d\d) - (\?\?|10|0\d)
constrains matches to strings starting with two digits, a space, a dash, and a space, and then either "??", "10", or "0" followed by a digit.
This part of your regular expression: (\?\?|10|0\d) should be changed to (\?\?|10|\d\d). The zero is changed to a \d. in the first string, that part of the string is 01, while the second string has 12, not matching the regular expression.