5

Possible Duplicate:
Javascript percentage validation

I want to allow 0.00 to 100.00 only.

function ValidateText(i)
    {

        if(i.value.length>0)
        {
         i.value = i.value.replace(/[^\d.d]+/g, '');

        }
    }
<asp:textbox id="txtrate" runat="server" Width="200px"  onkeyup= "javascript:ValidateText(this)"></asp:textbox>

It allows 0-9.0-9. Help me please. Thanks

Community
  • 1
  • 1
z0mbie
  • 57
  • 1
  • 1
  • 10

7 Answers7

12

Now this is some popular question!

This should do:

function validate(s) {
  return s.match(/^(100(\.0{1,2})?|[1-9]?\d(\.\d{1,2})?)$/) != null;
}

var test = [
  '3.0',
  '5',
  '99.99',
  '100',
  '100.00',
  '100.01',
  '101',
  '0.3',
  '.5',
  '0.567',
];

for (i=0; i<test.length; ++i) {
  WScript.StdOut.WriteLine(test[i] + ' => ' + validate(test[i]));
}

Outputs:

3.0 => true
5 => true
99.99 => true
100 => true
100.00 => true
100.01 => false
101 => false
0.3 => true
.5 => false
0.567 => false

Edit: the regexp can be shortened a bit without changing its meaning, credits to 6502

/^(100(\.00?)?|[1-9]?\d(\.\d\d?)?)$/
Community
  • 1
  • 1
SnakE
  • 2,355
  • 23
  • 31
  • 1
    I'd use non-capturing groups `(?:...)` where possible. – Qtax Jul 06 '11 at 08:13
  • @Qtax, any particular reason for that? – SnakE Jul 06 '11 at 08:16
  • no need to waste capturing groups/back refs where they are not needed, see http://stackoverflow.com/questions/5293986/why-not-create-a-backreference – Qtax Jul 06 '11 at 08:18
  • Why the **** can't I start my comment with `@SnakE, `? It just gets removed. QQ – Qtax Jul 06 '11 at 08:22
  • @Qtax, in this particular case it is utterly obvious that none of the groups are used to capture anything. So I don't think it's feasible to go into the pains of cluttering the already non-trivial regexp with more weird characters. – SnakE Jul 06 '11 at 08:33
10

This expression should allow only what you are asking for

/^[1-9]?\d(\.\d\d?)?|100(\.00?)?)$/

Meaning is

^            start of string
(            start of sub-expression ("or" between two possibilities)
  [1-9]?     an optional non-zero digit
  \d         followed by a digit
  (\.\d\d?)? optionally followed with a dot and one or two digits
|            or
  100        the string "100"
  (\.00?)?   optionally followed by a dot and one or two zeros
)            end of sub-expression
$            end of string
6502
  • 112,025
  • 15
  • 165
  • 265
  • Great solution, i have a minor improvement though: Replace the first digit \d by "[1-9]". This way only digits without leading zeroes are allowed. /^([1-9]\d?(\.\d\d?)?|100(\.00?)?)$/ – Bas Que Mar 29 '21 at 11:24
  • @BasQue: that expression wouldn't allow `0.3`, thanks for noticing the 03 problem tho – 6502 Mar 29 '21 at 20:00
3

Try this one

^(?:\d{1,2}(?:\.\d{1,2})?|100(?:\.0?0)?)$

See it here on Regexr

(?:) are non capturing groups, that means the match from this group is not stored in to a variable.

\d{1,2} matches 1 or 2 digits

(?:\.\d{1,2})? This is optional, a . followed by 1 or two digits

or

100(?:\.0?0)?) matches 100 optionally followed by 1 or 2 0

^ matches the start of the string

$ matches the end of the string

Those two anchors are needed, otherwise it will also match if there is stuff before or after a valid number.

Update: I don't know, but if you want to disallow leading zeros and numbers without two digits in the fraction part, then try this:

^(?!0\d)(?:\d{1,2}(?:\.\d{2})|100\.00)$

I removed the optional parts, so it needs to have a dot and two digits after it.

(?!0\d) is a negative lookahead that ensures that the number does not start with a 0 and directly a digit following.

stema
  • 90,351
  • 20
  • 107
  • 135
  • i.value = i.value.match(^(?:\d{1,2}(?:\.\d{1,2})?|100(?:\.0?0)?)$); i try this way.But it still allows 0-9.0-9 . – z0mbie Jul 06 '11 at 08:01
  • @z0mbie, what do you want to disallow? A leading 0 or a single digit after the dot or what do you not like? – stema Jul 06 '11 at 08:05
  • ,A leading 0 is no problem . I just want within 0 to 100 . Within this range, user can type float pattern too. Thanks for your help. – z0mbie Jul 06 '11 at 08:56
0

How about:

var x = '76', // (i.value)
    testx = Number(x.match(/\d+/)[0]);
console.log(testx>=0 && testx<=100);

Applied in your function:

function ValidateText(i) {
 var val = i.value;
 if (val.length>0)  {
   var test = Number(val.match(/\d+/)[0]);
   return test >=0 && test <= 100;
 }
 return false;
}
KooiInc
  • 119,216
  • 31
  • 141
  • 177
0

Use this:

function ValidateText(i)
{
    if(i.value.length>0)
    {
        i.value = i.value.match(/[1?\d{1,2}\.\d\d]/)[0];
    }
}

instead of replacing all that is not (0.00 - 100.00) (as it seems to me you are trying to do), I match the allowed strings and replace the original variable content with only the matched string.

Keep in mind that this will work if you only have 1 match. If you have more, you have to trick a bit the expression and decide how to concatenate the array of results.

sergio
  • 68,819
  • 11
  • 102
  • 123
0

Use this regex: ^(?:100(?:\.0{1,2})?|[0-9]{1,2}(?:\.[0-9]{1,2})?)$

Kirill Polishchuk
  • 54,804
  • 11
  • 122
  • 125
0

I don't actually see this as primarily a regex problem. I'd probably write this, particularly if you want informative error messages out it:

HTML:

<input id="percentValue" type="text" size="20">
<input type="button" value="Check" onclick="checkPercent()">

Javascript:

function checkPercent() {
    var o = document.getElementById("percentValue");
    var val = o.value;
    if (val.length == 0) {
        alert("Empty value");
        return;
    }
    var index = val.search(/[^0-9\.]/);
    if (index != -1) {
        o.selectionStart = o.selectionEnd = index;
        alert("Invalid characters");
        return;
    }
    if (val.match(/\./g).length > 1)
    {
        alert("Number must be of the form n.n");
        return;
    }
    var floatVal = parseFloat(val);
    if (floatVal < 0 || floatVal > 100)
    {
        alert("Value must be between 0.00 and 100.00");
        return;
    }
    alert("Valid value of: " + floatVal.toFixed(2));
}

jsfiddle here: http://jsfiddle.net/jfriend00/rDbAp/

jfriend00
  • 683,504
  • 96
  • 985
  • 979