I need to do dynamic validation on a number while user giving input. Number format should be-- before decimal it should restrict 12 digit and after decimal 2 digit.
I have written one validation function using Onkeyup and by giving maxlength. But I am facing issue like, if I remove one digit after decimal then its allowing more than 13 digit before decimal.
below function I have written for validation
function validation(e){
var t = e.value;
if( t.indexOf(".") <= 0 ) {
e.value = t.substr(0,12);
}
if( ( t.slice( 0, e.selectionStart ).length >= ( t.indexOf(".") + 3 ) ) {
e.value = ( t.indexOf(".") >= 0 ) ?
( t.substr( 0, t.indexOf(".") ) + t.substr( t.indexOf("."), 3 ) ) :
t
}
Appreciate any help!!
Thanks.
Regex
You can use a regular expression (regex).
For instance:
^(([1-9]{1}[0-9]{0,11}|[0-9]{1}))(\.\d{1,2})?$
Ok let's check out:
Numbers before the decimal point: ([1-9]{1}[0-9]{0,11}|[0-9]{1})
So either [1-9]{1}[0-9]{0,11} or [0-9]{1}, where the first expression prevents leading zeros and second expression makes the input o f 0 possible.
These expressions are followed by an optional decimal point (\.\d{1,2})?. The ? means that the expression can be there 0 or 1 times (so the input can be a decimal number or not). After the decimal point there have to be one 1 or 2 numbers (decimals).
You can try the expressions here: Online regex tester and debugger.
This should work:
123456789123
123.40
0
0.0
953
953.1
953.0
953.01
953.12
This should not work:
1234567891239 // 13 numbers
000.12 // leading zeros
123.001 // Too many decimals
Implementation
Possibility 1 is to insert the regex directly into the <input> using the pattern attribute. Possibility 2 is to do the validation via javascript. Note that you have to escape the backslashes \\.
let pattern = '^(([1-9]{1}[0-9]{0,11}|[0-9]{1}))(\\.\\d{1,2})?$';
let regex = new Regex(pattern);
function validation(e){
if(regex.test(e.value)){
// Value fits the pattern
}else{
// Value do not fit the pattern
}
}
I want to use Regex to match numbers between 0 to 25 both inclusive which can be doubles with 1 precision.
For ex.- 2, 2.5, 23.0, 8, 24.3, 25
I created following regex-
^(\\s*|0?[0-9]|[0-9]|1[0-9]|2[0-5])$
But it works only for numbers between 0 to 25 both inclusive.
This is the regex pattern I would use here:
^(?:(?:[0-9]|1[0-9]|2[0-4])(?:\.[0-9])?|25(?:\.0)?)$
Demo
The pattern is similar to what you used, except that we only match 2[0-4] with any single decimal point. The end point 25 is a special case, which can only take 25.0 at most for its decimal component.
But in general it would easier in JavaScript to just parse the text number, and then use an inequality to check the range. E.g.
var number = '24.3'
if (number >= 0 && number <= 25.0) {
console.log('within range');
}
To verify the validity, use the >= and <= operators. To meet the regex requirement, just add a garbage regex expression.
let isMatch = number => {
'must use regex'.match(/x/);
return number >= 0 && number <= 25;
};
I need to validate a user input for minutes, seconds, and hundredths in the format MM:SS:HH. However, user's input can not go over 10 minutes. I'm not sure how to limit that and still keep for example 01:01:01 valid.
/^[0-1][0-0]:[0-5][0-9]:[0-9][0-9]$/
This is the expression I had, but my example of 01:01:01 would not have worked.
Brief
I would definitely split the time string on : and then test each part. That's the simplest solution. Alternatively, you can do this relatively easily using regex.
Code
Method 1 - No regex
const str = ["00:00:00", "05:05:05", "10:00:00", "10:00:01", "10:59:59", "20:20:20"];
str.forEach(function(s) {
var a = s.split(":").map(Number);
if(a[0] < 10 || (a[0] === 10 && a[1] === 0 && a[2] === 0)) {
console.log(`Valid: ${s}`);
} else {
console.log(`Invalid: ${s}`);
}
});
Method 2 - Regex
const regex = /^(?:0\d(?::[0-5]\d){2}|10:00:00)$/;
const str = ["00:00:00", "05:05:05", "10:00:00", "10:00:01", "10:59:59", "20:20:20"];
str.forEach(function(s) {
if(regex.exec(s) !== null) {
console.log(`Valid: ${s}`);
} else {
console.log(`Invalid: ${s}`);
}
});
Explanation
I'll only explain the regex in Method 2 as the rest is fairly simple. If you need an explanation about any other parts, however, feel free to ask!
^ Assert position at the start of the line
(?:0\d(?::[0-5]\d){2}|10:00:00) Match either of the following
0\d(?::[0-5]\d){2} Match the following
0 Match this literally
\d Match any digit
(?::[0-5]\d){2} Match the following exactly twice
: Match this literally
[0-5] Match a number in the range between 0 and 5
\d Match any digit
10:00:00 Match this literally
$ Assert position at the end of the line
/(10:00:00|^0[0-9]:[0-5][0-9]:[0-5][0-9]$)/
['10:00:01', '10:00:00', '09:59:59', '05:05:05']
.forEach(t => console.log(t.match(/(10:00:00|^0[0-9]:[0-5][0-9]:[0-5][0-9]$)/)))
Your regex is close. Simply change your regex to:
/^(10:00:00|0[0-9]:[0-5][0-9]:[0-9][0-9])$/
I have seen a lot of functions that format telephone or number (comma and decimals) in stackflow community like this question here and others. Here's what I want to:
Step 1: Maintain a Library for patterns like this:
var library = {
fullDate : {
pattern : /^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/,
error : "Invalid Date format. Use YYYY-MM-DD format."
},
fullDateTime : {
pattern : /^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}$/,
error : "Invalid DateTime format. Use YYYY-MM-DD HH:MM (24-hour) format."
},
tel : {
pattern : /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
error : "Invalid Telephone format."
}
};
Step 2: Automatically add a character as they type. For exapmple, add a - after 4 numbers in Date.
I have a text field say:
<input type="text" data-validate="fullDate" placeholder="YYYY-MM-DD"/>
And possible place to start script as:
$('body').on('keyup','input',function(){
var validate = $(this).data('validate');
var pattern = library[validate].pattern;
//Some more steps here....
});
But, I cannot make any further because I am new to RegExp. Here's a startup fiddle. Anyone?
Further Notes: I have been able to validate using the following functions but what I want to is automatically make pattern:
function validate(libraryItem, subject){
var item = library[libraryItem];
if(item !== undefined){
var pattern = item.pattern;
if(validatePattern(pattern, subject)){
return true;
} else {
return item.error;
}
}
return false;
}
function validatePattern(pattern, subject){
return pattern.test(subject);
}
It is not as complicated as you think. What you are looking for is JQuery Masked input and other alternative libraries. Here is the documentation. All you need is:
<input id="date" type="text" placeholder="YYYY-MM-DD"/>
and the script:
$("#date").mask("9999-99-99",{placeholder:"YYYY-MM-DD"});
Here is demo pen link:
http://codepen.io/anon/pen/gpRyBp
To implement validation use this library:
https://github.com/RobinHerbots/jquery.inputmask
What needed here is breaking up the regular expression in sub expression which matches part of the string and suggest completion based upon next character in the Regular Expression.
I wrote a naive Parser which parses the expression and divides into atomic subexpression.
var parser = function(input) {
var tokenStack = [];
var suggestions = [];
var suggestion;
var lookAhead;
if (input[0] === '/')
input = input.slice(1, input.length - 1);
var i;
for (i = 0; i < input.length - 1; i++) {
lookAhead = input[i + 1];
switch (input[i]) {
case '(':
tokenStack.push('(');
break;
case '[':
tokenStack.push('[');
break;
case ')':
if (tokenStack[tokenStack.length - 1] === '(') {
tokenStack.pop();
if (tokenStack.length === 0) {
suggestion = generateSuggestion(input, i);
if (suggestion !== null)
suggestions.push(suggestion);
}
}
else
throw 'bracket mismatch';
break;
case ']':
if (lookAhead === '{') {
while (input[i] !== '}')
i++;
}
if (tokenStack[tokenStack.length - 1] === '[') {
tokenStack.pop();
if (tokenStack.length === 0) {
suggestion = generateSuggestion(input, i);
if (suggestion !== null)
suggestions.push(suggestion);
}
}
else
throw 'bracket mismatch';
break;
default:
if (tokenStack.length === 0) {
suggestion = generateSuggestion(input, i);
if (suggestion !== null)
suggestions.push(suggestion);
}
break;
}
}
return suggestions;
}
var generateSuggestion = function(input, index) {
if (input[index].match(/[a-zA-Z\-\ \.:]/) !== null)
return {
'regex': input.slice(0, index) + '$',
'suggestion': input[index]
};
else
return null;
}
Here is sample input and output of parser()
parser('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/');
// output:
[ { regex: '^[0-9]{4}$', suggestion: '-' },
{ regex: '^[0-9]{4}-[0-9]{1,2}$', suggestion: '-' } ]
Thus on every keyup you need to check the list of RegExp generated by parser and if any of it matches the input then use the suggestion.
EDIT:
Edited generateSuggestion to match only full expression.
Here is sample fiddle: http://jsfiddle.net/a7kkL6xu/6/
With backspace ignored: http://jsfiddle.net/a7kkL6xu/7/
This could be done with a single regex.
This requires a MM:DD and HH:MM to be 2 digits and YYYY to be 4 digits on a
fully valid entry, but matches all the partials.
It could be made to allow a single digit validity for the 2 digit valid mentioned.
But doing so, will make premature suggestions on the - - [ ] : form.
If you want to not inject the suggestion, then 1 or 2 digits is fine.
JavaScript doesn't allow lookbehind assertions, so partial field expressions
are below the valid field expressions in their respective groups.
Basically what happens is the input is rewritten on each key press event.
All you do is match the current input within the event handler.
Without suggestions, you just write over the input with the entire match (group 0).
The match (group 0) will only contain a valid partial or full match.
The valid completed field capture groups are 1 through 5
[ Year, Month, Day, Hours, Minutes ]
The incomplete field captures are groups 6 through 10
[ Minutes, Hours, Day, Month, Year ]
This is the logic:
// Note 1 - can handle control chars by just returning.
// Note 2 - can avoid rewrite by keeping a global of last good,
// then return if current == last.
if ( last char of group 0 is a dash '-' or space ' ' or colon ':'
or any of groups 6 - 10 matched
or group 5 matched )
set input equal to the group 0 string;
else if ( group 4 matched ) // Hours
set input equal to group 0 string + ':';
else if ( group 3 matched ) // Day
set input equal to group 0 string + ' ';
else if ( group 1 or 2 matched ) // Year or Month
set input equal to group 0 string + '-';
else // Here, effectively strips bad chars from input box
// before they are displayed.
set input equal to group 0 string;
Note that if a group didn't match it's value will be NULL
and to check the entire validity, there should be no partials and
groups 1 - 3 must be complete for just YYYY-MM-DD or 1 - 5 with the optional
time HH:MM
Final Note: This is a parser, and effectively a test case of the look and feel, ie. flicker, of real time input rewrite.
If it goes well, the logic in the handler can include Day validation (and rewrite) based on the month.
Also, the premise can be expanded to any type of input, any type of form and
form delimiter combinations, etc..
If it works, you can build a library.
# /^(?:(19\d{2}|20[0-1]\d|202[0-5])(?:-(?:(0[1-9]|1[0-2])(?:-(?:(0[1-9]|[1-2]\d|3[0-1])(?:[ ](?:(0\d|1\d|2[0-3])(?::(?:(0\d|[1-5][0-9])|([0-5]))?)?|([0-2]))?)?|([0-3]))?)?|([01]))?)?|(19\d?|20[0-2]?|[12]))/
^ # BOL
(?:
( # (1 start), Year 1900 - 2025
19 \d{2}
| 20 [0-1] \d
| 202 [0-5]
) # (1 end)
(?:
- # -
(?:
( # (2 start), Month 00 - 12
0 [1-9]
| 1 [0-2]
) # (2 end)
(?:
- # -
(?:
( # (3 start), Day 00 - 31
0 [1-9]
| [1-2] \d
| 3 [0-1]
) # (3 end)
(?:
[ ] # space
(?:
( # (4 start), Hour 00 - 23
0 \d
| 1 \d
| 2 [0-3]
) # (4 end)
(?:
: # :
(?:
( # (5 start), Minutes 00 - 59
0 \d
| [1-5] [0-9]
) # (5 end)
|
( [0-5] ) # (6)
)?
)?
|
( [0-2] ) # (7)
)?
)?
|
( [0-3] ) # (8)
)?
)?
|
( [01] ) # (9)
)?
)?
|
( # (10 start)
19 \d?
|
20 [0-2]?
|
[12]
) # (10 end)
)
It is only possible to add a character if it is the single possible choice at this point. An example would be a regex for the YYYY-MM-DD HH24:mm format: the -, the : and the (space) could be added. Here is the corresponding regex (/ ommitted to make it more readable, it is stricter than the one in the question, some illegal dates are still possible like 31st of February):
^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01]) (?:[01][0-9]|2[0-3]):[0-5][0-9]$
For fixed length inputs you could use #DineshDevkota's solution to add the literals and verify the whole text with regex. I think it's the cleanest and simplest solution. You could also capture the year, month and day to verify the day mathematically. Also rules like "date not in the future" or "max. 100 years in past" can only be veryfied in JS and not with just regex.
The only additional patterns that come to mind where a character could be automatically added:
A + after a literal, e.g. on A+ add an A
Minimal occurances in general, e.g. on (?:foo){2,5} add foofoo not to be confused with [fo]{2,5} where no characters can be added
Literals after the max length of a variable part, e.g. on (?:foo){1,3}bar add bar after the text is foofoofoo before it is not possible.
Add remainders e.g. foo|bar add ar when b was typed and oo when f was typed (also possible in the pattern shown in 3.) but this won't work for ^[a-z]+?(?:foo|bar)$ because we don't know when the user plans on ending the text and it can get really complicated (foo|flo|flu|food|fish only sh can be added after fi).
As seen in 3. and 4. those additional cases where characters could be added are of very limited use as soon as there are parts with variable length. You would have to parse the regex, split it in literal and regex parts. Then you have to parse/analyse the regex parts to incorporate the additional cases mentioned above where characters could be added. Really not worth the trouble if you ask me. (Not a single character can be added in your tel pattern.)
I have a datetime textbox which contains both date and time .
I want to validate the time.For the date i have validated.
e.g datetime value is 04/23/2013 05:26 pm;
I need a regex which can validate the time that will be in format 00:00:00 .
all are digits and no special character or other than digits will be entered.
i want only to validate dd:dd:dd all are 2 digits.
I can enter for example 10:10:10 and 01:02.
i have tried with js way like this.i have no knowledge in regex.so i want suggestions.
function ValidateDate()
{
//getting the value from textbox
var dateVal=document.getElementById('txtDateTime').value;
//after one space there is time..as i am using a datepicker and timepicker format
var time=dateVal.split(' ')[1];
var isValidTime=CheckTime(time);
}
function CheckTime(time)
{
var timePart=time.split(":");
var hour = timePart[0];
var minute = timePart[1];
var second = timePart[2];
if((parseInt(hour,10)<0) || (parseInt(hour,10)>59))
{
return false;
}
if((parseInt(minute)>59) || (parseInt(minute)<0))
{
return false;
}
if((parseInt(second)<0) || (parseInt(second)>59))
{
return false;
}
return true;
}
Thanks for your suggestions.
A simple regex of /^([0-1][0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9]))?$/g will work.
10:00:00 - OK
01:00:00 - OK
60:00:00 - Fail
30 - Fail
30:00 - Fail
23:59 - OK
24:00 - Fail
23:60:60 - Fail
23:59:59 - OK
Regex autopsy:
^ - This is where the sentence MUST start
([0-1][0-9]|2[0-3])
[0-1][0-9] - The digits 0 to 1 followed by any digit between 0 and 9
| - OR
2[0-3] - The digit 2 followed by any digit between 0 and 3
: - A literal : character
([0-5][0-9]) - The digits from 0 to 5 followed by any digit between 0 and 9
(?::([0-5][0-9]))?
?: - a non capturing group
: - A literal : character
([0-5][0-9]) - The digits from 0 to 5 followed by any digit between 0 and 9
? - means that the previous statement should be there 0 or 1 time (so it doesn't have to be there).
$ - This is where the sentence MUST end
The following regex should work: /^\d{2}:\d{2}(?::\d{2})?$/.