【问题标题】:Format all numbers in a single string (Java) [closed]将所有数字格式化为单个字符串(Java)[关闭]
【发布时间】:2021-04-15 08:29:24
【问题描述】:

我一直在为我的 AP CSP 课程试验一个计算器应用程序,但在开发过程中遇到了障碍。我一直在尝试格式化字符串中的所有数字以添加逗号,但事实证明这相当困难。

这是我想要实现的输入和输出示例:

Input: "1081+34-3954"
Output: "1,081+34-3,954"

我尝试过使用 String#split,但这并没有真正奏效,因为它变得非常大且重复。

【问题讨论】:

  • “我尝试过使用 String#split,但这并没有真正起到作用,因为它变得非常大且重复。” -- 很高兴看到此代码作为 minimal reproducible example 显示问题。
  • This thread 可能会有所帮助,但您仍然需要解析数字,可能使用像 \\d+replaceAll 或类似的正则表达式。
  • 你可以在 "\\b" 上拆分,它在单词之间的边界上拆分。
  • 如果 s 是您的第一个示例,则 s.split("\\b") 拆分为“1081”、“+”、“34”、“-”、“3954”

标签: java formatting format


【解决方案1】:

你可以使用正则表达式来做到这一点。

  • (\\d+) - 为整数捕获块一。
  • ([+-]|$) - 为操作员或行尾捕获块 2
String s = "1081+34-3954";

Pattern p = Pattern.compile("(\\d+)([/*+-]|$)");
Matcher m = p.matcher(s);

StringBuilder sb = new StringBuilder();

while (m.find()) {
    sb.append(String.format("%,d%s", Integer.valueOf(m.group(1)), m.group(2)));
}
String result = sb.toString();

System.out.println(result);

打印

1,081+34-3,954
  • String.format() 采用与 System.out.printf() 相同的参数
  • %,d 格式化整数,用逗号作为千位分组分隔符
  • %s为字符串获取操作符。

但是,如果这只是一个示例,并且您的模式更复杂,您将不得不对其进行调整。查看以下内容了解更多信息。

【讨论】:

  • 一开始可以,但经过进一步测试,如果字符串包含'*'或'/',它会中断。到目前为止谢谢!
  • 警告: 结果取决于区域设置,例如在法国,结果是1 081+34-3 954
  • @Lightcaster5 我在回答中确实说过,如果字符串更复杂,则必须进行调整。所以就像我为你做的那样,在字符类的[] 之间添加/*。您可以通过在 String.format 方法中指定 Locale 来更改组分隔符,我也提供了链接。
  • @WJS,抱歉,我一定读过那部分。一切都按预期运行!非常感谢您的帮助,您的解决方案非常聪明!
【解决方案2】:

您可以只使用简单的 String 和 StringBuilder 方法:

public class Test {
  public static String splitStr(String input) {
    StringBuilder str = new StringBuilder();
    boolean change = false;
    if (input.charAt(input.length() - 1) != '+' || input.charAt(input.length() - 1) != '-') {
      input = new StringBuilder(input).append('+').toString();
      change = true;
    }
    int lastIdx = 0;
    for(int i = 0; i < input.length(); i++){
      StringBuilder subStr = new StringBuilder();
      if (input.charAt(i) == '-' || input.charAt(i) == '+') {
       subStr.append(input.substring(lastIdx,i));
       for(int j = subStr.length() - 3; j >= 0; j-=3) {
        subStr.insert(j, ',');
       } 
       lastIdx = i + 1;
      str.append(subStr);
      str.append(input.charAt(i));
      }
    } 
    if (change) {
      str.delete(str.length() - 1, str.length());
    }
    return str.toString();
  }
  public static void main (String[] args) {
    String str = "1081+34-3954";
    String newStr = splitStr(str);
    System.out.println(newStr);
  }
}

【讨论】:

    【解决方案3】:

    您可以使用正则表达式替换,方法是搜索数字,然后解析并重新格式化它们。

    在 Java 9+ 中,这样做:

    String input = "1081+34-3954";
    
    DecimalFormat fmt = new DecimalFormat("#,##0", DecimalFormatSymbols.getInstance(Locale.US));
    String result = Pattern.compile("\\d+{4,}").matcher(input)
                           .replaceAll(n -> fmt.format(Long.parseLong(n.group())));
    System.out.println(result); // prints: 1,081+34-3,954
    

    任何不是 4 位以上数字的文本都保持不变。

    在较旧的 Java 版本中,使用替换循环:

    String input = "1081+34-3954";
    
    DecimalFormat fmt = new DecimalFormat("#,##0", DecimalFormatSymbols.getInstance(Locale.US));
    StringBuffer buf = new StringBuffer();
    Matcher m = Pattern.compile("\\d+{4,}").matcher(input);
    while (m.find())
        m.appendReplacement(buf, fmt.format(Long.parseLong(m.group())));
    String result = m.appendTail(buf).toString();
    System.out.println(result); // prints: 1,081+34-3,954
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      相关资源
      最近更新 更多