i'd like to make a javascript validation that will accept all numeric and decimal point format.
For example :
1,000,000.00 is OK 1.000.000,00 is OK1.000,000.00 is not OK
1.000,000,00 is not OK 1,000.000,00 is not OK 1,000.开发者_StackOverflow中文版000.00 is not OKBased on what i got here is :
/^[1-9][0-9]{0,2}(,[0-9]{3})*(\.[0-9]{2})?$/
is only valid for 1,000,000.00 not for 1.000.000,00
How can i validate both format ?
Updated :
What if the thousand points are not compulsory such as :
1000000.00 is OK or 1000000,00 is OKAssuming that the decimal part and thousands separators are mandatory, not optional, and that 0 is not an allowed value (as suggested by your examples and your regex):
^[1-9]\d{0,2}(?:(?:,\d{3})*\.\d{2}|(?:\.\d{3})*,\d{2})$
As a verbose regex:
^ # Start of string
[1-9]\d{0,2} # 1-3 digits, no leading zero
(?: # Match either...
(?:,\d{3})* # comma-separated triple digits
\.\d{2} # plus dot-separated decimals
| # or...
(?:\.\d{3})* # dot-separated triple digits
,\d{2} # plus comma-separated decimals
) # End of alternation
$ # End of string
Here is the regex that you want..
^(([1-9]\d{0,2}(((\.\d{3})*(,\d{2})?)|((,\d{3})*(\.\d{2})?)))|(0(\.|,)\d{1,2})|([1-9]\d+((\.|,)\d{1,2})?))$
This is the link that proves that it can handles all cases
http://regexr.com?2tves
The best way to look at a regular expression this big is to blow it up to a very large font and split it on the alternatives (|)
var s='1,000,000.00';// tests
var result= /(^\d+([,.]\d+)?$)/.test(s) || // no thousand separator
/((^\d{1,3}(,\d{3})+(\.\d+)?)$)/.test(s) || // comma thousand separator
/((^\d{1,3}(\.\d{3})+(,\d+)?)$)/.test(s); // dot thousand separator
alert(result)
Put together its a brute-
function validDelimNum2(s){
var rx=/(^\d+([,.]\d+)?$)|((^\d{1,3}(,\d{3})+(\.\d+)?)$)|((^\d{1,3}(\.\d{3})+(,\d+)?)$)/;
return rx.test(s);
}
//tests
var N= [
'10000000',
'1,000,000.00',
'1.000.000,00',
'1000000.00',
'1000000,00',
'1.00.00',
'1,00,00',
'1.000,00',
'1000,000.00'
]
var A= [];
for(var i= 0, L= N.length; i<L; i++){
A.push(N[i]+'='+validDelimNum2(N[i]));
}
A.join('\n')
/* returned values
10000000=true
1,000,000.00=true
1.000.000,00=true
1000000.00=true
1000000,00=true
1.00.00=false
1,00,00=false
1.000,00=true
1000,000.00=false
*/
The simplest (though not most elegant by far) method would be to write analogous RE for another case and join them with 'OR', like this:
/^(([1-9][0-9]{0,2}(,[0-9]{3})*(\.[0-9]{2})?)|([1-9][0-9]{0,2}(\.[0-9]{3})*(,[0-9]{2})?))$/
UPDATE
A little cleaned up version
/^[1-9]\d{0,2}(((,\d{3})*(\.\d{2})?)|((\.\d{3})*(,\d{2})?))$/
You can replace the ,
and \.
with [,.]
to accept either in either location. It would also make 1,000.000.00
OK though.
Its harder to make the regexp behave like that in JavaScript because you can't use lookbehinds
/^(0|0[.,]\d{2}|[1-9]\d{0,2}((,(\d{3}))*(\.\d{2})?|(\.(\d{3}))*(,\d{2})?))$/
/^ #anchor to the first char of string
( #start group
0 # 0
| # or
0[.,] # 0 or 0 followed by a . or ,
\d{2} # 2 digits
| # or
[1-9] #match 1-9
\d{0,2} #0-2 additional digits
( #start group
(,(\d{3}))* # match , and 3 digits zero or more times
(\.\d{2})? # match . and 2 digits zero or one
| # or
(\.(\d{3})* # match . and 3 digits zero or more times
(,\d{2})? # match , and 2 digits zero or one time
) #end group
) #end group
$/ #anchor to end of string
http://jsfiddle.net/AC3Bm/
精彩评论