Java regular expression to validate numeric comma separated values

csv, java, numeric, regex

Solution

FINISHED

The final result is:

"(?!$)[\\+-]?([1-9]\\d{0,2}|0)?(\\,\\d{3})*(\\.\\d+)?"

Change since the last update is:([.][\d]+)?

plus in this block makes impossible situation when user inputs number then puts dot but nothing after it.

New update: added 2 "\" into last block to avoid entering comma or other symbol instead of dot.

New update: Thanks to user2266098 and nhahtdh.

user2266098 pointed my attention on the uncharted problem of "0.1" number and showed solution with adding "|0" to the second block. But his regexp doesn't work correctly with "+" and "-" for my data. And I don't like the quantifier "{0,}" instead of "*" because of it's size.

nhahtdh pointed my attention on the uncharted problem of empty string and showed solution with "(?!$)".

Thanks to everyone!

Update

There are new conditions for this case:

I need to make a regular expression with such numbers valid:

"+1", "1.0", "1,233", "1,233,456.34", "-1", ".34", "1,345,234,122,123", "0.1"

and these invalid:

"++1", "1.0.0", "1,23,3", "+-1233456.34", "002", "1.", "a1", "1,,2", "1 2", "1,2", ",2", "", "0,123"

I still can't get "perfect" regexp =)

"(?!$)[\\+-]?([1-9]\\d{0,2}|0)?(\\,\\d{3})*(\\.\\d+)?"

gives: Invalid number is detected as valid: 0,123

Problem

I need to make a regular expression with such numbers valid: ``` "+1", "1.0", "1,233", "1,233,456.34", "-1", ".34", "1,345,234,122,123" ``` and these invalid: ``` "++1", "1.0.0", "1,23,3", "+-1233456.34", "002", "1.", "a1", "1,,2", "1 2", "1,2", ",2". ``` I've tried different variants of this regexp: ``` "[\\+\\-]?[1-9]{0,3}([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\.][\\d]*)?" ``` Code for testing: ``` import java.util.regex.Matcher; import java.util.regex.Pattern; public class REGEX { private static final String REGEX = "[\\+\\-]?[1-9]{0,3}([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\d]{3}[\\,]{1})?([\\.][\\d]*)?"; private static String[] validNumbers = { "+1", "1.0", "1,233", "1,233,456.34", "-1", ".34", "1,345,234,122,123" }; private static String[] invalidNumbers = { "++1", "1.0.0", "1,23,3", "+-1233456.34", "002", "1.", "a1", "1,,2", "1 2", "1,2", ",2" }; public static void main(String[] args) { Pattern pattern = Pattern.compile(REGEX); for (String number : validNumbers) { Matcher matcher = pattern.matcher(number); if (!matcher.matches()) { System.out.println("Valid number is detected as invalid: " + number); } } for (String number : invalidNumbers) { Matcher matcher = pattern.matcher(number); if (matcher.matches()) { System.out.println("Invalid number is detected as valid: " + number); } } } ``` } When the console will be empty then the task is done. Now I've such problems: Valid number is detected as invalid: 1,233 Valid number is detected as invalid: 1,233,456.34 Valid number is detected as invalid: 1,345,234,122,123 Invalid number is detected as valid: 1. Regards. Sorry for big size. Update. Thanks to Noob UnChained, I've progressed to this regexp: ``` ^([\\+\\-]?[1-9]\\d{0,2})*(\\,\\d{3})*([\\.][\\d*])?$ ``` and now there is fewer problems: Valid number is detected as invalid: 1,233,456.34 Valid number is detected as invalid: .34 Update. regexp: ``` "([\\+\\-]?[1-9]\\d{0,2})*(\\,\\d{3})*([.][\\d]*)?" ``` problems: Invalid number is detected as valid: 1. FINISHED The final result is: ``` "(?!$)[\\+-]?([1-9]\\d{0,2}|0)?(\\,\\d{3})*(\\.\\d+)?" ``` Change since the last update is:([.][\d]+)? plus in this block makes impossible situation when user inputs number then puts dot but nothing after it. New update: added 2 "\" into last block to avoid entering comma or other symbol instead of dot. New update: Thanks to user2266098 and nhahtdh. user2266098 pointed my attention on the uncharted problem of "0.1" number and showed solution with adding "|0" to the second block. But his regexp doesn't work correctly with "+" and "-" for my data (because of "()" instead of "[]"). And I don't like the quantifier "{0,}" instead of "*" because of it's size. nhahtdh pointed my attention on the uncharted problem of empty string and showed solution with "(?!$)". Thanks to everyone! Update There are new conditions for this case: I need to make a regular expression with such numbers valid: ``` "+1", "1.0", "1,233", "1,233,456.34", "-1", ".34", "1,345,234,122,123", "0.1" ``` and these invalid: ``` "++1", "1.0.0", "1,23,3", "+-1233456.34", "002", "1.", "a1", "1,,2", "1 2", "1,2", ",2", "", "0,123" ``` I still can't get "perfect" regexp =) ``` "(?!$)[\\+-]?([1-9]\\d{0,2}|0)?(\\,\\d{3})*(\\.\\d+)?" ``` gives: Invalid number is detected as valid: 0,123

Original source

Related problems