价格格式无法匹配逗号

price formatting fails to match commas

我有这个测试:

@Test
public void succeedsWhenFormatWithTwoCommas(){
    String input = "#,###,###.##";

    PriceFormatValidator priceFormatValidator = new PriceFormatValidator();
    boolean answer = priceFormatValidator.validate(input);

    assertTrue(answer);
}

运行此代码时失败:

public boolean validate(String input) {
    Pattern pattern = Pattern.compile("^#{1,3}(,?#{3})?(\.#{0,3})?$");
    Matcher matcher = pattern.matcher(input);
    boolean isValid = matcher.matches();

    return isValid;
}

这是为什么

您可以通过以下方式替换您的图案:

Pattern pattern = Pattern.compile("^#{1,3}(,?#{3}){1,2}(\.#{0,3})?$");

你的 ^#{1,3}(,?#{3})?(\.#{0,3})?$ 正则表达式只允许 1 或零 ,### 在里面,因为 (,?#{3})? 匹配一个可选的序列 1 或 0 , 后跟恰好 3 # 符号。

您需要将 (,?#{3})? 部分变成 (,#{3})* 以允许 , + 三个 # 符号的零个或多个序列。

使用

"^#{1,3}(,#{3})*(\.#{0,3})?$"

参见regex demo

整个模式现在将匹配以下内容:

  • ^ - 字符串开头
  • #{1,3} - 一比三 #
  • (,#{3})* - 零个或多个 ,+3 # 个符号序列
  • (\.#{0,3})? - 一个可选的 . + 0 到 3 # 个符号
  • $ - 字符串结尾。

注意:末尾的 (\.#{0,3})? 允许尾随 .。如果您不想这样,请将其更改为 (\.#{1,3})?.

注意 2:如果您不使用捕获的值(与 (...) 模式匹配的值),最好将捕获组更改为非捕获那些(即 (...)(?:...))。