Regex - Quantity Field - javascript

I want to validate the contents of a quantity field using Javascript's Regular Expressions.
Valid input would be an integer number, from zero upwards. If leading zeros could be removed too that would be great.
Examples
1 Pass
0 Pass
01 Failed
00 Failed
-1 Failed
1.1 Failed
1000000 Pass
I have tried myself, but the best I got was...
var regex = /[0-9]{1,9}/;
...which doesn't fail on negative numbers, or numbers with leading zeros.
Thanks!

This regular expression matches any sequence of digits without a leading 0 (except for 0 itself, which is handled separately).
var regex = /^0$|^[1-9][0-9]*$/;
^ and $ are anchors, which anchor the match to the beginning and end of the string. This means, nothing is allowed before or after the number, and as such, no minus can be included.

If you want to remove leading zeros instead of forbidding them, then you can use this:
^0*(\d{1,9})$
Now you will find the number without trailing zeros in captured group no. 1 (even if only one 0 was entered).

Try ^\d+$. Should match positive integers.

var re = /^0*([^0]\d*)$/;
var match = re.exec(str);
if (match) {
var i = parseInt(match[1], 10);
}
else {
//whoops, not an integer
}
(match[1] returns the int without leading zeroes, match[0] the entire matched string).

Related

Adding zero to non leaded zero datetime string regex

I have the following datetime string 2020-5-1 1:2 I used the pattern (\W)(\d{1}) to match any digit with length 1 i.e non zero leaded, 5,1,1,2. This demo shows that pattern succeeded to catch them in the group 2 for every match.
Using Javascript's String replace method, I have tried to turn the datetime sample string to be 2020-05-01 01:02. In this jsbin that runs the following snippet:
var txt = '2020-5-1 1:2'
var output = [];
output[0] = txt.replace(/(\W)(\d{1})/gi,'0$1');
output[1] = txt.replace(/(\W)(\d{1})/gi,'0$2');
console.log(output);
// The output: ["20200-0-0 0:", "202005010102"]
In the first output's entry, it does unexpected behavior, instead of adding 0 to the match, it replaced it with 0! How could I solve this issue?
You only used a single placeholder in the replacement pattern, but in the regex pattern, you consumed two substrings with two capturing groups, so one is lost.
To add 0 before single digits you may use
txt.replace(/\b\d\b/g,'0$&')
txt.replace(/(^|\D)(\d)(?!\d)/g,'$10$2')
txt.replace(/(?<!\d)\d(?!\d)/g,'0$&') // With the ECMAScript2018+
Here, \b\d\b matches a digit that is neither preceded nor followed with an ASCII letter, digit or _. The substitution is 0 and the whole match value, $&.
The (^|\D)(\d)(?!\d) pattern capture start of string or a non-digit char into Group 1, then a digit is captured in Group 2. Then, (?!\d) makes sure there is no digit immediately to the right. The substitution is $10$2, Group 1 value, 0 and then Group 2 value.
The (?<!\d)\d(?!\d) pattern matches any digit not enclosed with other digits, and the substitution is the same as in Case 1.
JS demo:
var txt = '2020-5-1 1:2';
console.log( txt.replace(/\b\d\b/g,'0$&') )
console.log( txt.replace(/(^|\D)(\d)(?!\d)/g,'$10$2') )

limit total number of characters in regex

The string can be a number or a set of numbers, or two groups of numbers separated with "-", but total count of all characters mustn't be more than 6.
Example of valid strings
5
55-33
4444-1
1-4444
666666
Example of invalid strings
-3
6666-
5555-6666
My regex
/^\d+(-?\d+)?$/
But this regex interprets 5555-6666 as a valid string, though its length is more than 6 characters.
I tried following
/^(\d+(-?\d+)?){1,6}$/
but, than I recognized that it interpret enclosed charset as one group, which it expects from 1 to 6.
So how to control total number of chars just with a regexp and requirements described above?
Mehotd 1 :-
Easiest thing you can do it test the length before regex ( i will prefer using this method which checks length and then use regex )
str.length < 7 && /^\d+(-?\d+)?$/.test(str)
Method 2 :-
You can use positive lookahead
^(?=.{0,6}$)\d+(-?\d+)?$
Regex Demo
You can use a positive lookahead pattern to ensure that there can be a maximum of 6 characters:
^(?=.{1,6}$)\d+(?:-\d+)?$
Demo: https://regex101.com/r/kAxuZp/1
Or you can a negative lookahead pattern to ensure that the string does not start with a dash, and another negative lookahead pattern to ensure that the string does not contain two dashes:
^(?!-)(?!.*-.*-)[\d-]{0,5}\d$
Demo: https://regex101.com/r/kAxuZp/3
One option would be to use your current regex pattern and also check the length of the input with dash removed:
var input = "4444-1";
if (/^\d+(-?\d+)?$/.test(input) && input.replace("-", "").length <= 6) {
console.log("MATCH");
}
else {
console.log("NO MATCH");
}
Note that checking the length of the input is only really meaningful after the dash has been removed, because it is only then that we can assert the total number of actual digits.

Regular expression for opposite of integer without leading zeros

I have a regex for integers with leading zero and it works fine. I am using it like:
value = value.replace(/[^0-9]/, '');
Now, I want another regex for integers without leading zero. So, I got the below mentioned regex from stackoverflow answer:
[1-9]+[0-9]*
As I am using string.replace, I have to invert the regex. So my final code looks like:
value = value.replace(/^(?![1-9]+[0-9]*)$/, '');
But now resulting value is always empty.
Expectations:
User should be allowed to typein these examples:
123456
123
78
User should not be able to type in these characters:
0123
e44
02565
asdf
02asf
754ads
Also, if I get a regex for only decimals without leading 0 and no e and should work in value.replace, then it will be a bonus for me.
I don't know how to construct regex patterns. So, if this a very basic question, then please forgive me.
Try
value = "e044".replace(/^.*?([1-9]+[0-9]*).*$/, '$1');
return 44
I would do it in two steps.
First remove the leading part (remove anything which is not a 1-9 at the beginning)
value = value.replace(/^[^1-9]*/, '');
then remove the trailing parts (match any number(s) in the beginning and remove the rest)
value = value.replace(/(?![0-9]+).*/, '');
for decimals use this (credits drkunibar):
value = value.replace(/.*?([1-9]+[0-9]*[\.]{0,1}[0-9]*).*/,'$1');
Please try this:
match = /^[1-9]\d*$/.test(value);
match will contain a boolean,true if the user enters a number without 0 in the lead,false-for anything other than number without 0 in the lead.

How to limit a string length

I have the following regex:
^[a-zA-Z_][\-_a-zA-Z0-9]*
I need to limit it's length to 39 characters. I tried the following but it didn't work:
^[a-zA-Z_][\-_a-zA-Z0-9]*{,38}
You just need to use a limited quantifier {0,38} and an end of string anchor $:
^[a-zA-Z_][-_a-zA-Z0-9]{0,38}$
^^^^^ ^
The syntax for the limited quantifiers is {min,max} where the max parameter is optional, but the minimum should be present. Without $ you may match 39 first characters in a much longer string.
You do not have to escape a hyphen when it is placed at the beginning of a character class (thus, I suggest removing it).
Also, you can further shorten the regex with an /imodifier:
/^[a-z_][-_a-z0-9]{0,38}$/i
or even
/^[a-z_][-\w]{0,38}$/i
Regarding the question from the comment:
wouldn't also that version work (^[a-zA-Z_][-_a-zA-Z0-9]){0,39}$ with 39 characters limit?
The regex matches
(^[a-zA-Z_][-_a-zA-Z0-9]){0,39} - 0 to 39 sequences of...
^ - start of the string
[a-zA-Z_] - a single character from the specified range
[-_a-zA-Z0-9] - a single character from the specified range
$ - end of string
So, you require a match to include sequences from the start of the string. Note a start of string can be matched only once. As you let the number of such sequences to be 0, you only match either the location at the end of the string or a 2 character string like A-.
Let's see what the regex does with the Word input. It mathces the start of string with ^, then W with [a-zA-Z_], then o with [-_a-zA-Z0-9]. Then the group ends, and that equals to matching the group once. Since we can match more sequences, the regex tries to match r with ^. It fails. So, the next position is retried and failed the same way, because d is not the ^ (start of string). And that way the end of string is matched because there is a 0 occurrences of ^[a-zA-Z_][-_a-zA-Z0-9] and there is an end of string $.
See regex demo
try
^[a-zA-Z_][\-_a-zA-Z0-9]{0,38}$
[0,38] means that number of instances of characters matching [\-_a-zA-Z0-9] could be 0 to 38.
I'm adding this in case you're limiting input field entry.
While not regex, I use this function and it works well (I will add that it's important to let the user know you're limiting the input length from UI/UX point of view):
limitLength: function(element, lengthOf){
var fieldLength = element.value.length;
if(fieldLength <= lengthOf){
return true;
} else {
var str = element.value;
str = str.substring(0, str.length - 1);
element.value = str;
}
}
Usage:
<input type="text" onInput="my.namespace.limitLength(this,39)">

Float number regex with unexpected results

I'm using this regex to validate float numbers:
var reg = /\d+\.?\d+/;
But it's validating this as true:
"11.34x"
"11.34abs"
"1a1.34abs"
The \d should only match numbers. What is happening?
If you don't anchor the regular expression, it will match a string that contains a substring that matches.
Try:
var reg = /^\d+\.?\d+$/;
The ^ matches the start of the test string, and $ matches the end. Thus that regular expression will only match strings that have nothing but digits and at most one ".".
edit — as pointed out, your use of the + quantifier means your regex requires digits; if there's a decimal point, then it requires digits on both sides. Maybe that's what you want, maybe it isn't.
use this regular expression ^\d+(\.\d+)?$
or ^\d+([.,]\d+)?$ separator can be comma or dot
Consider using the Number wrapper/constructor function instead:
Number('11.34'); // => 11.34
Number('11.34x'); // => NaN
[Edit] As commenter #VisioN points out, that function has an edge case for empty and pure-whitespace strings, so maybe create a wrapper function:
function reallyParseFloatingPointNumber(s) {
var s = (''+s).trim();
return (s==='') ? NaN : Number(s);
}
if (!"12 34.98 ".replace(/^\s+|\s+$/g,"").match(/^\d+\.?\d+$/))
alert("Please enter numbers in float form")
else alert ("Good Form, Old Chap!")
Alas, I am mistaken again! burning_LEGION is correct:
/^\d+(\.\d+)?$/
will match single digits too.

Categories

Resources