Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java regular expression to validate numeric comma separated values

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

like image 797
Yaroslav Selivanov Avatar asked Apr 16 '13 15:04

Yaroslav Selivanov


People also ask

How do you match a comma in regex?

Starting with the carat ^ indicates a beginning of line. The 0-9 indicates characters 0 through 9, the comma , indicates comma, and the semicolon indicates a ; . The closing ] indicates the end of the character set. The plus + indicates that one or more of the "previous item" must be present.

Can you write a regular expression to check if string is a number?

Same regular expression for checking String for numbers can also be written without using predefined character set and using character class and negation as shown in following example : Pattern pattern = Pattern. compile(". *[^0-9].


2 Answers

This one works for me on all your test data:

^(\\+|-)?([1-9]\\d{0,2}|0)?(,\\d{3}){0,}(\\.\\d+)?

btw I expect you also want 0.1 to be a match, but your regexp doesn't work on it. I can't comment, so I'm writing this in an answer

like image 45
NeplatnyUdaj Avatar answered Sep 27 '22 22:09

NeplatnyUdaj


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

like image 161
Yaroslav Selivanov Avatar answered Sep 27 '22 21:09

Yaroslav Selivanov