You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中验证葡萄牙式欧洲数字格式?

葡萄牙式欧洲数字格式验证问题

有效格式示例

  • 1.234,56
  • 1 234,56(单个空格作为千位分隔符)
  • 1.234.567,89
  • 1 234 567,89(单个空格作为千位分隔符)
  • 1 234,56(多空格可替换为单个空格,属于常见手写格式)

无效格式示例

  • 1,234.56(误用英文格式分隔符)
  • 1.234 56(空格用作小数点分隔符)
  • 1,234,567.89(英文格式)
  • 1 234.56(多空格且小数点格式错误)

问题与现有代码

我需要验证这类葡萄牙式欧洲数字格式,但自己尝试模式匹配效果不好,有没有可用的第三方库?另外我写了一段代码,可能存在问题,代码如下:

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;
import java.util.Objects;

public class ValidateEuropeanNumber {

    /**
     * Checks if the input string represents a valid European number format.
     *
     * Preconditions:
     *  - The input string must not be null.
     *
     * Postconditions:
     *  - Returns true if the input string represents a valid European number format.
     *  - Returns false if the input string does not represent a valid European number format.
     *
     * @param input The string to check for a valid European number format.
     * @return true if the input string represents a valid European number format, false otherwise.
     * @throws NullPointerException if the input string is null.
     */
    public static boolean isValidEuropeanNumber(String input) {
        Objects.requireNonNull(input, "The input string must not be null.");

        // Remove leading and trailing spaces
        input = input.trim();

        // Replace multiple spaces with a single space
        input = input.replaceAll("\\s{2,}", " ");

        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.GERMAN);
        DecimalFormat format = new DecimalFormat("#,##0.###", symbols);
        format.setParseBigDecimal(true);

        try {
            BigDecimal number = (BigDecimal) format.parse(input);

            // Check if there are any periods in the input
            if (input.contains(".")) {
                DecimalFormatSymbols periodSymbols = new DecimalFormatSymbols(Locale.UK);
                DecimalFormat periodFormat = new DecimalFormat("#,##0.###", periodSymbols);
                periodFormat.setParseBigDecimal(true);

                BigDecimal periodNumber = (BigDecimal) periodFormat.parse(input);
            }

            return true;
        } catch (ParseException e) {
            return false;
        }
    }
}

现有代码问题

这段代码有几个明显问题:

  1. 用了Locale.GERMAN的格式符号,但葡萄牙的数字格式和德语区不同,应该用葡萄牙本地语言环境
  2. 额外的英文格式解析逻辑会把无效的英文格式(比如1,234.56)误判为有效
  3. DecimalFormat默认不开启严格解析,会忽略部分格式错误,导致误判

改进后的原生代码实现

不需要第三方库的话,可以调整代码适配葡萄牙格式,同时开启严格解析:

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParsePosition;
import java.util.Locale;
import java.util.Objects;

public class ValidateEuropeanNumber {

    /**
     * 检查输入字符串是否为有效的葡萄牙式欧洲数字格式
     *
     * @param input 待检查的字符串
     * @return 有效返回true,无效返回false
     * @throws NullPointerException 如果输入为null
     */
    public static boolean isValidPortugueseNumber(String input) {
        Objects.requireNonNull(input, "输入字符串不能为空");

        // 处理首尾空格,把多个空格替换成单个空格
        String cleanedInput = input.trim().replaceAll("\\s{2,}", " ");
        // 统一把空格千位分隔符替换成.,适配葡萄牙格式的解析规则
        String normalizedInput = cleanedInput.replace(' ', '.');

        // 使用葡萄牙(葡萄牙语)的格式符号:千位分隔符是.,小数点是,
        DecimalFormatSymbols ptSymbols = new DecimalFormatSymbols(Locale.forLanguageTag("pt-PT"));
        // 定义格式:整数部分至少一位,千位用.分隔,小数部分最多三位
        DecimalFormat format = new DecimalFormat("#,##0.###", ptSymbols);
        format.setParseBigDecimal(true);
        // 开启严格解析,必须完全匹配格式
        format.setParseStrict(true);

        ParsePosition pos = new ParsePosition(0);
        format.parse(normalizedInput, pos);

        // 只有整个字符串都被解析完成,才判定为有效
        return pos.getIndex() == normalizedInput.length();
    }
}

关键优化点

  • 用Locale.forLanguageTag("pt-PT")匹配葡萄牙本地数字格式规则
  • 先统一处理空格分隔符,把空格替换成.,避免解析不兼容
  • 开启严格解析模式,确保格式完全符合要求
  • 用ParsePosition检查解析是否覆盖整个字符串,防止部分有效但整体无效的情况

第三方库方案

如果想简化开发,可以用Apache Commons Lang或者ICU4J这类成熟的工具库:

Apache Commons Lang 示例

import org.apache.commons.lang3.math.NumberUtils;
import java.util.Locale;
import java.util.Objects;

public class ValidateWithCommons {
    public static boolean isValidPortugueseNumber(String input) {
        Objects.requireNonNull(input, "输入字符串不能为空");
        
        String cleaned = input.trim().replaceAll("\\s{2,}", " ").replace(' ', '.');
        // 使用葡萄牙语环境解析,确保格式匹配
        return NumberUtils.isParsable(cleaned, Locale.forLanguageTag("pt-PT"));
    }
}

需要引入Maven依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

内容的提问来源于stack exchange,提问作者Tushar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 21:42:15