Regular expression in Java for parsing money

Tags: ,



I’m looking for are regex for parsing money amounts. The String s10 should not match. Can someone help, or can someone simplify the regex? That’s my try:

    public static String[] getMoney(String s) {
        List<String> ret = new ArrayList<String>();
        String regex = "((\d{1,3}[.,]?)(\d{3}[.,]?)*[.,]\d{1,2})(\D|$)";
        Pattern pat = Pattern.compile(regex);
        Matcher mat = pat.matcher(s);
        while (mat.find()) {
            ret.add(mat.group(1));
        }
        return ret.toArray(new String[0]);
    }

    public static void main(String[] args) {
        String s1 = "0,1"; // should match
        String s2 = ",1"; // should not match
        String s3 = "1,"; // should not match
        String s4 = "1.234,01"; // should match
        String s5 = "1234,10"; // should match
        String s6 = "1234,100"; // should not match
        String s7 = "1234,10a"; // should match
        String s8 = "123,456,789.10"; // should match
        String s9 = "123.456.789,10"; // should match
        String s10 = "123,456.789,10"; // should not match (!)

        System.out.println(Arrays.toString(getMoney(s1)));
        System.out.println(Arrays.toString(getMoney(s2)));
        System.out.println(Arrays.toString(getMoney(s3)));
        System.out.println(Arrays.toString(getMoney(s4)));
        System.out.println(Arrays.toString(getMoney(s5)));
        System.out.println(Arrays.toString(getMoney(s6)));
        System.out.println(Arrays.toString(getMoney(s7)));
        System.out.println(Arrays.toString(getMoney(s8)));
        System.out.println(Arrays.toString(getMoney(s9)));
        System.out.println(Arrays.toString(getMoney(s10)));
    }

Answer

I think you may use

(?<![d,.])(?:d{1,3}(?:(?=([.,]))(?:1d{3})*)?|d+)(?:(?!1)[.,]d{1,2})?(?![,.d])

See the regex demo

Details

  • (?<![d,.]) – no digit, . or , allowed immediately on the left
  • (?:d{1,3}(?:(?=([.,]))(?:1d{3})*)?|d+)
    • d{1,3}(?:(?=([.,]))(?:1d{3})*)? – one, two or three digits followed with an optional occurrence of a position followed with a comma or dot followed with 0 or more occurrences of the captured value and then any three digits
    • |d+ – or 1 or more digits
  • (?:(?!1)[.,]d{1,2})? – an optional sequence of a comma or dot, but not the same char as in Group 1, and then 1 or 2 digits
  • (?![,.d]) – no digit, . or , allowed immediately on the right

In Java, do not forget to double the backslashes:

String regex = "(?<![\d,.])(?:\d{1,3}(?:(?=([.,]))(?:\1\d{3})*)?|\d+)(?:(?!\1)[.,]\d{1,2})?(?![,.\d])";


Source: stackoverflow