1

Tring Allow to both Integer as well as Decimal as input. And restricting on total length which should not be greater that 11(MaximumLength of input including decimal point) eg. Allowed values are 1.0, 1.123546, 12345678912,12.12345678,...etc. i.e. If value contain Decimal point then allow at least one digit after Decimal point otherwise allow complete integer number with maximum length i.e. 11

I have declared regular expression as: /^-?(([0-9]{0,11}) | ([0-9]{0,9}.[0-9]{1,2}))$/

And the values I'm testing against as: 6666666.666

But the result always not getting matched.

NOTE: If length of digit before decimal point is 7 then allow 3 digit after decimal point in case Maximum allowed length is 11. Fractional part length decided based on integral part.

------------------------ JQuery Function-----------------------------------

function Validate(sender, precision)
{
    var variable;
    if (precision != "0") 
    {
        var valueLength = sender.value.indexOf('.');
        if (sender.id.indexOf("Longitude") > -1)
            variable = "-?[0-9,]{0," + parseInt($(sender).attr("data-length") - (parseInt(precision) + 1)) + "}[.][0-9]{0," + parseInt(precision) + "}$";
        else
        variable = "-?(([0-9]{0," + parseInt($(sender).attr("data-length")) + "})|([0-9]{0," + parseInt($(sender).attr("data-length") - 2) + "}.[0-9]{1," + parseInt

        ($(sender).attr("data-length") - (valueLength + 2)) + "}))$";
    }
    else
        variable = "-?[0-9,]{0," + parseInt($(sender).attr("data-length")) + "}$";
        var re = new RegExp('^' + variable);
    if (sender.value != "") 
    {
        if (!re.test(sender.value)) 
        {
            alert('Not Matched');
        }
        else
        {
            alert('Matched');
        }
    }

}

Kaishu
  • 377
  • 1
  • 7
  • 21

2 Answers2

2

First, . is a special character in a regular expression which matches any character, so your expression matches more than you're expecting.

More importantly, you're explicitly looking for {0,9} characters before the decimal and {0,2} after it, and the example you gave of 6666666.666 has more than two decimals.

Why not simply

if (/^[0-9]+(\.[0-9]+)?$/.test( sender.value ) && sender.value.length <= 11) ...

Let the regex worry about the numbers and formatting and deal with the length separately. Length is easy to check without mucking around with regex variations.

VoteyDisciple
  • 37,319
  • 5
  • 97
  • 97
  • This is ok for other fields but there are another fields like `latitude` and `longitude` where I'm restricting user with the format as 99.999999999 and 999.999999999999 respectively but this condition allows those fields to take integral part more that 2 and three digit for lat and long... How to handle these combine condition.? – Kaishu Mar 22 '16 at 10:04
  • 1
    You cannot have a single test for both "any number of digits before or after the decimal as long as the total length is 11 or fewer characters" and "any number of characters long but with only two or three digits before the decimal". Write one test for one and a completely separate test for the other. (In the latter case it's `/^[0-9]{2,3}(\.[0-9]+)$/`) – VoteyDisciple Mar 22 '16 at 10:14
  • I don't know why it allowing value as (`111.`) . As we have restricted to insert atleast one digit after decimal point still it allows empty fractional part after decimal point. – Kaishu Mar 22 '16 at 10:24
  • 1
    My expression explicitly ends with `?` so the decimal component is not required. If you need it to be required, don't use a `?` there. – VoteyDisciple Mar 22 '16 at 11:47
2

If you want to use regex only, an idea is to use a negative lookahead for checking max length.

^-?(?!.{12})\d+(?:\.\d+)?$
  • ^-? an optional hyphen at ^ start
  • (?!.{12}) the lookahead checks if there's not more than 11 of any characters ahead.
  • \d+ matches one or more \d which is a short for digit [0-9]
  • (?:\.\d+)? followed by an optional group containing a dot followed by one or more digits.
  • $ matches the end

See demo at regex101

Community
  • 1
  • 1
bobble bubble
  • 16,888
  • 3
  • 27
  • 46
  • I have insert above mentioned expression in function I've put above but still `re.test(sender.value)` always returning false... – Kaishu Mar 22 '16 at 11:18
  • @Kaishu Try `/^-?(?!.{12})\d+(?:\.\d+)?$/.test(sender.value)` [works fine (fiddle)](https://jsfiddle.net/osfdrw4p/). – bobble bubble Mar 22 '16 at 11:23
  • this works, so what is the problem in function where I'm using this.? – Kaishu Mar 22 '16 at 11:27
  • @Kaishu If you use with `new RegExp` need more escaping: `var re = new RegExp('^-?(?!.{12})\\d+(?:\\.\\d+)?$');` [see fiddle](https://jsfiddle.net/osfdrw4p/1/). – bobble bubble Mar 22 '16 at 11:30