匹配法语浮点数的Java正则表达式不匹配空格

时间:2018-12-08 10:07:49

标签: java regex formatting internationalization numbers

我正在用英语,西班牙语和法语为BigDecimal数字编写一个简单的验证。我想接受纯数字(例如(1234.56或1234,56,具体取决于小数点分隔符的区域设置))和带格式的数字(英语为1234.56,西班牙语为1.234.56,法语为1234.56)。我已经用英语和西班牙语做到了这一点,并且我已经成功测试了它,但是法语却失败了。

public static void main(final String[] args) {
    System.out.println( "es 1.234.567,89 : " + "1.234.567,89".matches("(((\\d{1,3})([.]\\d{3})*)|(\\d+))([,]\\d+)?") );
    System.out.println( "en 1,234,567.89 : " + "1,234,567.89".matches("(((\\d{1,3})([,]\\d{3})*)|(\\d+))([.]\\d+)?") );
}

输出:

es 1.234.567,89 : true
en 1,234,567.89 : true

但是,当我尝试使用法语分组分隔符执行此操作时,请验证falis。

    public static void main(final String[] args) {
    System.out.println( "fr 1 234 567,89 : " + "1 234 567,89".matches("(((\\d{1,3})([ ]\\d{3})*)|(\\d+))([,]\\d+)?") );
}

输出:

fr 1 234 567,89 : false

这也会失败:

    public static void main(final String[] args) {
    System.out.println( "fr 1 234 567,89 : " + "1 234 567,89".matches("(((\\d{1,3})(\\s\\d{3})*)|(\\d+))([,]\\d+)?") );
}

输出:

fr 1 234 567,89 : false

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

您可以使用java.text.NumberFormat,它已经内置了针对不同语言环境的规则。

    System.out.println( NumberFormat.getInstance(Locale.ENGLISH).parse("123,456.56") );
    System.out.println( NumberFormat.getInstance(Locale.FRENCH).parse("123 456,56") );
    System.out.println( NumberFormat.getInstance(new Locale("es-es")).parse("123.456,56") );

答案 1 :(得分:0)

这是一个正则表达式,可以精确匹配您所有的格式。

^\d{1,3}(?:([., ])?\d{3})?(?:\1\d{3})*(?:(?!\1)[,.]\d+)?$

说明:

  • ^->匹配字符串的开头
  • \d{1,3}->匹配一到三位数字
  • (?:([., ])?\d{3})?->此处([., ])捕获点,逗号或空格,并将第1组放入后向引用中,因为不允许将其用作十进制数字定界符,并且此字符集是可选的以便匹配普通数字。其次,\d{3}跟随三位数字,并且该组的全部是可选的,以匹配没有点,逗号或空格的整数。
  • (?:\1\d{3})*->此部分用于匹配点,逗号或空格,无论是在group1中捕获的任何内容,其后都是三位数,并且可以重复出现零次或多次。
  • (?:(?!\1)[,.]\d+)?->最后,这将捕获小数部分,其中负向(?!\1)不允许在group1中捕获什么,但允许逗号或点后跟一个或多个数字,成为小数的一部分
  • $->匹配输入结尾

匹配,

1.234.567,89
1.234.567
1.234
24
1234.56
1234
1,234,567.89
1 234 567,89
1 234 567,89

不匹配

1.234.567.89
12.234.
1,234,567,89
1,234.567.89
1 234.567,89

Demo

您的Java代码,

System.out.println("es 1.234.567,89 : "
        + "1.234.567,89".matches("^\\d{1,3}(?:([., ])\\d{3})?(?:\\1\\d{3})*(?:(?!\\1)[,.]\\d+)?$"));
System.out.println("en 1,234,567.89 : "
        + "1,234,567.89".matches("^\\d{1,3}(?:([., ])\\d{3})?(?:\\1\\d{3})*(?:(?!\\1)[,.]\\d+)?$"));
System.out.println("fr 1 234 567,89 : "
        + "1 234 567,89".matches("^\\d{1,3}(?:([., ])\\d{3})?(?:\\1\\d{3})*(?:(?!\\1)[,.]\\d+)?$"));
System.out.println("fr 1 234 567,89 : "
        + "1 234 567,89".matches("^\\d{1,3}(?:([., ])\\d{3})?(?:\\1\\d{3})*(?:(?!\\1)[,.]\\d+)?$"));
System.out.println("1234.56: "
        + "1 234 567,89".matches("^\\d{1,3}(?:([., ])\\d{3})?(?:\\1\\d{3})*(?:(?!\\1)[,.]\\d+)?$"));
System.out.println("1234: "
        + "1 234 567,89".matches("^\\d{1,3}(?:([., ])\\d{3})?(?:\\1\\d{3})*(?:(?!\\1)[,.]\\d+)?$"));

打印

es 1.234.567,89 : true
en 1,234,567.89 : true
fr 1 234 567,89 : true
fr 1 234 567,89 : true
1234.56: true
1234: true