We help IT Professionals succeed at work.

How do I validate salary form field using reg exp?

posconsultant
on
Medium Priority
3,297 Views
Last Modified: 2008-02-01
Hi all,

    I need to validate a salary field for a form using Javascript, and I can't find a good example of this anywhere on the web.  The salary can be from $0 to, say, $100,000,000, and can include only digits or commas or decimals in the right places.
    I found some old code from another project but it does not work well:
function valsal(obj) {    
     codeToVal = obj.value;
     var pattern =/([0-9]{1,9})[,]*([0-9]{3,3})*[,]*([0-9]{1,3})*[.]*([0-9]{2,2})*/
     var matchArray = pattern.exec(codeToVal)
     if (matchArray)
     {        
        return true
     }
     else
     {
          alert('Invalid. Format must be ###.##')
          obj.value = ''
          obj.focus()
          return false
     }
}  

     The problem with this is that it allows alpha chars ie "xyz44" or "44,000.xyz".  I only half understand the syntax of this as I'm sorta new to Reg Exp but I suspect problem lies in the logic, specifically the use of the "*".  
     If anyone can give me an example of how to do this I would greatly appreciate it.  Thanks!
Comment
Watch Question

Commented:
Use this pattern:

=/^([0-9]{1,9})[,]*([0-9]{3,3})*[,]*([0-9]{1,3})*[.]*([0-9]{2,2})*$/

The first caret ^ strictly specifies the start of the string. The last dollar sign $ strictly specifies the end of the string.
Hey, not to be anal, but this is a bit more precise:
=/^([0-9]{1,9})[,]*([0-9]{3,3})*[,]*([0-9]{1,3})*([.]([0-9]{2,2})){0,1}$/
The previous solution will let you enter many periods followed many "pairs of numbers", so
11,000...0000 would be okayed.
my solution prevents that.

Commented:
Good point djsputnik. But you missed the commas. Shorter version:

/^(\d{1,3},)*(\d{1,3})*(\.\d{2})?$/

Keep it Cool!

Commented:
A better version. The first one will allow the user to have 029,123456789.09...

/^(\d{1,3},)*(\d{1,3})?(\.\d{2})?$/

;-)
Try this:
/^((\d{1,3})(,\d{3,3})*|\d+)(\.\d{2})?$/
( 1st clause: 1,2 or 3 digits
2nd clause: any number of ",###" )
or
( just digits )
last clause : either ".##" or nothing

The first clause in the previous solution allowed you to have 11,123,1,... - 1 to 3 digits followed by a comma. You only want 3 digits at a time.

I think eventually we'll nail it :)

Commented:
djsputnik,

Your last suggestion will allow 029,123456789.09 because of the addition of |\d+.


:-)
etmendz
hey etmendz,
notice that the \d+ is "OR"ed with the whole ((\d{1,3})(,\d{3,3})* , not just (,\d{3,3})*. I think I correctly allow for either numbers with ",###"'s or just numbers without commas. If you still think it's incorrect let me know.
Commented:
djsputnik,

Because it is an OR, the 029,123456789.09 will be allowed. Remember, regular expressions do not match against the first true instance in your OR but will rather parse against all possibile matches as defined in your regular expession.

Once the regular expression engine matches the left side of your OR, it does not mean that the right side of your OR will never be evaluated when the engine proceeds reading to the end of the string. This means that the rest of your string may still be matched against the right side of your OR. I am still confident that this makes the best match:

/^(\d{1,3},)*(\d{1,3})?(\.\d{2})?$/

Try this out posconsultant!

If you want to force numbers when the user enters decimal values:

/^(\d{1,3},)*(\d{1,3})+(\.\d{2})?$/

Notice the "+" sign this time.

If you want to require the decimal values (at least 0.00), just remove the last ? before the last $.

Have fun!

Author

Commented:
Thanks!  This is a big, big help.

Regular expressions...aren't.

You guys are sick, sick, sick ;-)

posconsultant