检查字符串在 Java 中是不是有小数部分:涉及语言环境

Posted

技术标签:

【中文标题】检查字符串在 Java 中是不是有小数部分:涉及语言环境【英文标题】:Checking if a String has a fraction part in Java : Locale involved检查字符串在 Java 中是否有小数部分:涉及语言环境 【发布时间】:2018-08-01 07:20:31 【问题描述】:

我有一个String 值,它可以包含LongDoubleString 可能基于 Locale

所以它可能包含以下值:

11
11.00
15,25 (for Locale like Denmark where the decimal part is denoted by a comma instead of dot)

我只想在它是 Double 时才做某事;从某种意义上说,它包含一个分数值。 “00”的小数值也是有效的情况。

if(string contains fraction)
  // do something

鉴于以上三个示例,对于 11.0015,25,控制权应该在 if 内,但对于 11 则不是。

我该如何检查?

请记住,涉及区域设置。所以点和逗号对于不同的语言环境可能有不同的含义。如此简单的正则表达式来查找它们的出现是行不通的。例如如果 Locale 是澳大利亚,则 11,00 是 1100,因此不是双精度数。但如果 Locale 是丹麦或德国等欧洲国家/地区,则 11,00 是双倍。

我需要使用NumberFormat 找到一些解决方案,但无法解决。

我有区域设置信息。所以我知道字符串是否属于哪个语言环境。鉴于此,我怎样才能找到 String 是否有分数?

【问题讨论】:

那么检查它是否不仅包含数字?或 chekc 是否包含逗号或点? @gcandal 如果小数点或逗号可能是分隔符,您需要使用两个 Locales 进行解析。 你是如何区分 11,001 英语和 11,001 丹麦语的呢?如果没有更多信息,您的问题将无法解决 @Nik 哪个区域设置适用?虚拟机之一?还是以某种方式作为参数提供? 看看this question。在接受答案的 cmets 中,他们提到了 new DecimalFormatSymbols(myLocale).getDecimalSeparator(),这应该使您能够构建正确的正则表达式。 【参考方案1】:

编辑:由于您已编辑您的问题,说明您知道语言环境,您可以将它与NumberFormat.getNumberInstance(locale).parse(strValue) 结合使用正则表达式作为逗号和千位分隔符。这里是一个测试代码:

import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

class Main
  private static final Locale DUTCH = new Locale("nl","NL");

  public static void main(String[] a)
    test("11", Locale.ENGLISH);
    test("11", DUTCH);
    System.out.println();
    test("11.00", Locale.ENGLISH);
    test("11.00", DUTCH);
    System.out.println();
    test("11,00", Locale.ENGLISH);
    test("11,00", DUTCH);
    System.out.println();
    test("15.123", Locale.ENGLISH);
    test("15.123", DUTCH);
    System.out.println();
    test("15,123", Locale.ENGLISH);
    test("15,123", DUTCH);
    System.out.println();
    test("something", Locale.ENGLISH);
    test("something", DUTCH);
  

  static void test(String val, Locale locale)
    try
      DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
      char decimalSep = symbols.getDecimalSeparator();
      char thousandSep = symbols.getGroupingSeparator();

      String escapedDecimalSep = decimalSep == '.' ? "\\." : decimalSep+"";
      String escapedThousandSep = thousandSep == '.' ? "\\." : thousandSep+"";

      String intRegex = "\\d+(" + escapedThousandSep + "\\d3)*"; // Example ENGLISH: "\\d+(,\\d3)*"
      String doubleRegex = intRegex + escapedDecimalSep + "\\d+"; // Example ENGLISH: "\\d+(,\\d3)*\\.\\d+"

      NumberFormat format = NumberFormat.getInstance(locale);
      Number number = format.parse(val);
      if(val.matches(doubleRegex))
        double d = number.doubleValue();
        System.out.println(val + " (in locale " + locale + ") is a double: " + d);
       else if(val.matches(intRegex))
        int i = number.intValue();
        System.out.println(val + " (in locale " + locale + ") is an integer: " + i);
       else
        System.out.println("Unable to determine whether value " + val + " is an integer or double for locale " + locale);
      
     catch(ParseException ex)
      System.out.println("Error occurred for value \"" + val + "\". Are you sure it's an integer or decimal?");
    
  

Try it online.

这是输出:

11 (in locale en) is an integer: 11
11 (in locale nl_NL) is an integer: 11

11.00 (in locale en) is a double: 11.0
Unable to determine whether value 11.00 is an integer or double for locale nl_NL

Unable to determine whether value 11,00 is an integer or double for locale en
11,00 (in locale nl_NL) is a double: 11.0

15.123 (in locale en) is a double: 15.123
15.123 (in locale nl_NL) is an integer: 15123

15,123 (in locale en) is an integer: 15123
15,123 (in locale nl_NL) is a double: 15.123

Error occurred for value "something". Are you sure it's an integer or decimal?
Error occurred for value "something". Are you sure it's an integer or decimal?

【讨论】:

谢谢.. 但这就是我正在做和努力的事情。 11,00 不应以 Integer 形式返回,而应以 Double 形式返回,因为它有分数(即使是 00)。 @Nik 我再次编辑。这次它使用了 Number-parse 和 regex 的组合。【参考方案2】:

使用正则表达式可以做到

Pattern decimalPattern = Pattern.compile("\\d+(,|\\.)\\d+2");

然后有

boolean isDecimal = decimalPattern.matcher(input).matches();

正则表达式:

\d+ 一位或多位数字 (,|\\.) 小数点或逗号 \d+ 又是一位或多位数字

或者你可以做分裂的事情

String[] split = input.split("(,|\\.)");
boolean isDecimal = split.length > 1 && split[1].length() == 2;

【讨论】:

11,000 for English Locale 不是双精度值,但会为您的解决方案返回 true。 @Nik 您的解决方案设计听起来不太适合您的任何问题。 @Nik 在第二个数字正则表达式部分之后添加了2。虽然严格来说 OP 没有指定这个限制,但它只出现在他的输入样本中。 @snr 不确定您的意思。不解决问题? @daniu 这与你无关。相反,OP。我不知道他有多少经验或多大年纪,但他的方法不是工程!我尊重你的回答。但是,我认为你是多余地浪费了时间【参考方案3】:

您可以使用循环来检查它是否有逗号或点,然后用 if 进行检查?

boolean IsADouble = false;
for (int i = 0; i < String.length(); i++) 
            if (String.charAt(i) == ','|| String.charAt(i) == '.') 
                IsADouble = true
            
        

然后你创建 If 来做某事,如果它是双精度的。

希望对你有所帮助:)

【讨论】:

11,000 for English Locale 不是双精度值,但会为您的解决方案返回 true。 因此您可以添加更多条件为真,例如 if is a double 可能只有 2 个零。以这种方式适应您的代码,我认为它可以工作@Nik

以上是关于检查字符串在 Java 中是不是有小数部分:涉及语言环境的主要内容,如果未能解决你的问题,请参考以下文章

检查 obj.value 是不是有小数部分

NSDecimalNumber 如何判断是不是有小数部分

java里如何在输出浮点数小数部分为0时自动将小数点和小数部分隐藏

JAVA如何检查小数位

如何判断一double类型的数值是不是有小数部分

爱沙尼亚语(et-EE)语言环境中的小数分隔符在 Windows 服务器中以点而不是逗号的形式出现