【问题标题】:How to shorten (format) String output properly?如何正确缩短(格式)字符串输出?
【发布时间】:2019-07-15 12:39:55
【问题描述】:

简单的问题作为初学者提出大问题。

我想缩短(格式化)一个字符串以仅显示 1 个小数或 2。不幸的是它是一个字符串而不是双精度。

String getNumber = "6.000m";

我知道有一个 printf() 函数,但据我所知,它是以正确的顺序打印多个字符串。

我怎样才能使输出只有一位小数,或者如果它有更多不是 0 的数字?

6.000 m --> 6.0
4.900 m --> 4.9
4.750 m --> 4.75

【问题讨论】:

  • 没有现有的功能可以完全满足您的需求。您需要解析字符串,提取数字,然后以所需格式打印出来。
  • 你的字符串总是格式为“m”吗?
  • 是的,它总是采用“ m”的格式

标签: java string output


【解决方案1】:

我假设它的末尾总是“m”,前面有一些可选的空格。所以我首先使用正则表达式删除它。 DecimalFormat 是您完成其余工作的好帮手:

import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Ff {
    static Pattern numberPart=Pattern.compile("([0-9.]*)\\b*m");
    static DecimalFormat df=new DecimalFormat("0.0#####");

    public static String format(String input)
    {
        Matcher m=numberPart.matcher(input);
        if(m.matches())
        {
            return df.format(Double.parseDouble(m.group(1)));
        }
        return null;
    }
    public static void main(String args[]) {
        System.out.println(format("6.000m"));
        System.out.println(format("4.900m"));
        System.out.println(format("4.750m"));
    }
}

输出是:

6.0
4.9
4.75

【讨论】:

  • 注意:最好将数组括号放在类型而不是变量名后面,即String[] args而不是String args[]
【解决方案2】:

你不应该使用正则表达式,因为它很难维护。

举个例子:

    (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01- 
    \x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?: 
    (?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0- 
    5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]| 
    [1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\ 
    [\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

这是使用正则表达式验证电子邮件的一些代码的一部分。那时,当计算机速度很慢时,正则表达式是必要的,因为正则表达式很快。现在您不再需要它们,维护是关键。

使用测试用例后:

  • 0.000 m -> 0.0
  • 1.000 m -> 1.0
  • 9.000 米 -> 9.0
  • 1.100 m -> 1.1
  • 1.900 m -> 1.9
  • 1.110 m -> 1.11
  • 1.010 m -> 1.01
  • 1.111 m -> 1.111
  • 1.101 m -> 1.101
  • 1.101m -> 1.101

我得出了这个结论:

shortenGivenNumber(String wholeNumber); 将是您用来缩短号码的方法。其他方法是为了使 main 方法更具可读性。

public class NumberShortener {

    public String shortenGivenNumber(String wholeNumber) {
        int endOfShortNumber = findEndOfNumber(wholeNumber);
        
        String shortenedNumber = cutOutNumber(wholeNumber, endOfShortNumber);
            
        return shortenedNumber;
    }

    private int findEndOfNumber(String numberWithZeroesAndM) {
        int lastZero = findIndexOfZeroAfterNumber(numberWithZeroesAndM);
        
        int endOfNumber = lastZero;
        
        endOfNumber = handleNo0AtEndCase(numberWithZeroesAndM, lastZero, endOfNumber);
        
        return endOfNumber;
    }

    private int findIndexOfZeroAfterNumber(String wholeNumber) {
        int lastZero; 

        int searchIndex = 3;
        boolean numberAfterZero;
        do {
            numberAfterZero = false;
            
            lastZero = findNextIndexOfZero(wholeNumber, searchIndex);
            numberAfterZero = isANumberAfterThisZero(wholeNumber, lastZero);
            
            searchIndex++;
        }while(numberAfterZero == true && valueExistsAtEnd(lastZero));
        
        return lastZero;
    }

    private int findNextIndexOfZero(String wholeNumber, int searchIndex) {
        return wholeNumber.indexOf("0", searchIndex);
    }

    private boolean isANumberAfterThisZero(String wholeNumber, int lastZero) {
        boolean numberAfterZero = false;
        
        for(int i = 1; i < 10; i++){
            char characterAfterZero = getCharacterAfterZero(wholeNumber, lastZero);
            char iAsChar = convertIntToChar(i);
            
            if(isTheCharacterThisNumber(characterAfterZero, iAsChar)){
                numberAfterZero = true;
            }
        }
        return numberAfterZero;
    }
    

    private boolean valueExistsAtEnd(int lastZero) {
        return lastZero != -1;
    }

    private int handleNo0AtEndCase(String wholeNumber, int lastZero, int endOfNumber) {
        if(thisSignIsntAtEnd(lastZero)){
            int indexOfSpace = getIndexOfSpace(wholeNumber);
            endOfNumber = indexOfSpace;
            endOfNumber = handleNoSpaceAtEndCase(wholeNumber, endOfNumber, indexOfSpace);
        }
        return endOfNumber;
    }

    private int getIndexOfSpace(String wholeNumber) {
        return wholeNumber.indexOf(" ");
    }

    private int handleNoSpaceAtEndCase(String wholeNumber, int endOfNumber, int space) {
        if(thisSignIsntAtEnd(space)) {
            int indexOfM = getIndexOfM(wholeNumber);
            endOfNumber = indexOfM;
        }
        return endOfNumber;
    }

    private int getIndexOfM(String wholeNumber) {
        return wholeNumber.indexOf("m");
    }

    private char getCharacterAfterZero(String wholeNumber, int indexOfZero) {
        int indexAfterZero = indexOfZero+1;
        return wholeNumber.charAt(indexAfterZero);
    }
    

    private char convertIntToChar(int i) {
        return (char) (i+48);
    }

    private String cutOutNumber(String wholeNumber, int endOfNumber) {
        return wholeNumber.substring(0, endOfNumber);
    }

    private boolean isTheCharacterThisNumber(char characterAfterZero, char iAsChar) {
        return characterAfterZero == iAsChar;
    }
}

它总是复制前 3 个字符 (x.x)。第一个 0(在 x.x 之后),后面没有任何数字,将用作指示最终数字子字符串结束的最后一个索引。如果直到最后有超过 0 的数字,它将使用空间(1.123 m)。如果没有空格,则使用 m (1.123m)。

【讨论】:

  • 我不相信你的代码比使用正则表达式的 10 行代码更容易维护。
  • 确实如此。更多的代码和更多的方法也不错。如果你例如想用“-”代替空格:
  • 你可以很容易地找到“-”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 2011-10-20
  • 1970-01-01
  • 2017-04-28
  • 1970-01-01
相关资源
最近更新 更多