检查字符串在 Java 中是不是有小数部分:涉及语言环境
Posted
技术标签:
【中文标题】检查字符串在 Java 中是不是有小数部分:涉及语言环境【英文标题】:Checking if a String has a fraction part in Java : Locale involved检查字符串在 Java 中是否有小数部分:涉及语言环境 【发布时间】:2018-08-01 07:20:31 【问题描述】:我有一个String
值,它可以包含Long
或Double
。 String
可能基于 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.00
和 15,25
,控制权应该在 if
内,但对于 11 则不是。
我该如何检查?
请记住,涉及区域设置。所以点和逗号对于不同的语言环境可能有不同的含义。如此简单的正则表达式来查找它们的出现是行不通的。例如如果 Locale 是澳大利亚,则 11,00 是 1100,因此不是双精度数。但如果 Locale 是丹麦或德国等欧洲国家/地区,则 11,00 是双倍。
我需要使用NumberFormat
找到一些解决方案,但无法解决。
我有区域设置信息。所以我知道字符串是否属于哪个语言环境。鉴于此,我怎样才能找到 String 是否有分数?
【问题讨论】:
那么检查它是否不仅包含数字?或 chekc 是否包含逗号或点? @gcandal 如果小数点或逗号可能是分隔符,您需要使用两个Locale
s 进行解析。
你是如何区分 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 中是不是有小数部分:涉及语言环境的主要内容,如果未能解决你的问题,请参考以下文章