如何从字符串中获取数字值?

3
如何拆分字符串?
我有一个字符串 String:
String s = "1+2*3(30+4/2-(10+2))*2+1";

有一个获取字符串中数字值的方法:

private static DigitStack getNumber(String convert) {
        String[] arr = convert.split("");
        digitStack = new DigitStack();

        try {
            for (int i = 0; i < arr.length ; i++) {
                while (arr[i].matches("\\d+")) {
                    digitStack.push(Double.valueOf(arr[i]));
                    i++;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        
        return digitStack;

    }

方法返回值:
1.0; 2.0; 3.0; [3.0  0.0]; 4.0; 2.0; [1.0  0.0]; 2.0; 2.0; 1.0;

期望输出:

   1.0; 2.0; 3.0; 30.0; 4.0; 2.0; 10.0; 2.0; 2.0; 1.0;

问题是方法计算每个符号都像独立的一样,比如数字30和10。它会转换为两个数字 [3.0 和 0.0] [1.0 和 0.0]

如何修复?


2
预期输出是什么? - Niclas Lindgren
您可能需要重新考虑convert.split("")。尝试打印arr的内容并查看它们如何改进。 - David Soroko
它们应该是那样的。 - Dartweiler
你可以获得两个运算符或符号之间的数字。 - Rajan1404930
字符串可能会发生变化,运算符和符号也可能会改变2。 - Dartweiler
显示剩余4条评论
5个回答

2

最简单的方法是在非数字字符上拆分字符串,例如:

String s = "1+2*3(30+4/2-(10+2))*2+1";
String[] arr = s.split("\\D+");

这将返回一个数组。
[1, 2, 3, 30, 4, 2, 10, 2, 2, 1]

您可以遍历这些数字并将其转换为double类型。

正如Rohit所指出的,如果您有带小数点的数字或者想要考虑负数,则此方法将不起作用。


0
String[] digits = Pattern.compile("\\d+")
            .matcher("1+2*3(30+4/2-(10+2))*2+1")
            .results()
            .map(MatchResult::group)
            .toArray(String[]::new);

\d+在正则表达式中表示一个或多个数字。

这将返回数组:

{ "1", "2", "3", "30", "4", "2", "10", "2", "2", "1" }

如果您想将此转换为数字数组:
double[] matches = Arrays.stream(digits)
        .mapToDouble(Float::parseFloat)
        .toArray();

0
假设您正在使用Java 9,您可以简单地获取正则表达式的所有匹配项,并将它们转换为double类型。
import java.util.regex.Pattern;
import java.util.regex.MatchResult; 

private static DigitStack getNumber(String convert) {
    digitStack = new DigitStack();

    try {
        String numbers[] = Pattern.compile("\\d(\\d+|\\.)+")
                      .matcher(convert)
                      .results()
                      .map(MatchResult::group)
                      .toArray(String[]::new);

        for(String number : numbers ) digitStack.push(Double.valueOf(number));

    }catch (Exception e){
        e.printStackTrace();
    }
    
    return digitStack;

}

你的代码问题在于你分别检查了每个字符。你需要先获取所有数字,然后将它们转换为双精度浮点数。

0

这将获取整数和浮点数值,假设它们在语法上是正确的。运算符、括号和变量将被忽略。

String str = "1.9+.2*3(30.2+4./2-(10.23+2))*2+1";
String[] digits = str.split("[^\\d\\.]+");
System.out.println(Arrays.toString(digits));

打印

[1.9, .2, 3, 30.2, 4., 2, 10.23, 2, 2, 1]

0

我的答案有点不同,因为我假设您最终想要运算符以及值。

以下是我其中一次测试运行的结果。

Original Equation:            1+2*3(30+4/2-(10+2))*2+1
Expanded Equation:            1 + 2 * 3 ( 30 + 4 / 2 - ( 10 + 2 ) ) * 2 + 1

看起来我所做的只是在方程式中添加了空格。实际上,我所做的是将方程式分成几个部分,并打印每个部分,然后加上一个空格。
以下是我编写的代码,用于从原始方程式创建一个List<String>的部分列表。
private List<String> parseEquation(String equation) {
    List<String> parts = new ArrayList<>();
    StringBuilder builder = new StringBuilder();
    String testCharacters = "+-*/()";
    char[] letters = equation.toCharArray();
    for (int i = 0; i < letters.length; i++) {
        if (letters[i] == ' ') {
            continue;
        }
        
        if (Character.isDigit(letters[i])) {
            builder.append(letters[i]);
            continue;
        }
        
        if (letters[i] == '.') {
            builder.append(letters[i]);
            continue;
        }
        
        if (contains(letters[i], testCharacters)) {
            addPart(parts, builder);
            parts.add(Character.toString(letters[i]));
        }
    }
    
    addPart(parts, builder);
    
    return parts;
}

private void addPart(List<String> parts, StringBuilder builder) {
    if (builder.length() > 0) {
        parts.add(builder.toString());
        builder.delete(0, builder.length());
    }
}

private boolean contains(char c, String text) {
    for (int i = 0; i < text.length(); i++) {
        char t = text.charAt(i);
        if (c == t) {
            return true;
        }
    }
    
    return false;
}

addPart方法是一个实用工具方法,用于检查空部分。如果该部分不为空,则此方法将该部分添加到List中。

contains方法是一个实用工具方法,允许我使用一个if语句检查所有的运算符和括号。

parseEquation方法不使用任何花哨的正则表达式。这很直接。

我检查方程式中的每个字符。如果字符是空格,则跳过该字符。如果字符是数字或小数点,则将其添加到StringBuilder以创建数字。如果字符是运算符或括号,则将前一个数字添加到部分List中,然后将运算符或括号添加到部分List中。

我使用continue语句跳过for循环的底部,并使代码更加整洁。我没有嵌套的if语句和continue语句。

这是完整可运行的代码。你可以通过注释的那一行看到我也写了一个方程求解器。那部分代码就留给你了。

import java.util.ArrayList;
import java.util.List;

public class EquationSolver {
    
    private static final String FORMAT = "%-30s";

    public static void main(String[] args) {
        String equation = "1+2*3(30+4/2-(10+2))*2+1";
        String title = String.format(FORMAT, "Original Equation:");
        System.out.println(title + equation);
        
        EquationSolver es = new EquationSolver();
        List<String> parts = es.parseEquation(equation);
//      es.processEquation(parts);
        title = String.format(FORMAT, "Expanded Equation:");
        System.out.println(title + es.toString(parts));
    }

    private List<String> parseEquation(String equation) {
        List<String> parts = new ArrayList<>();
        StringBuilder builder = new StringBuilder();
        String testCharacters = "+-*/()";
        char[] letters = equation.toCharArray();
        for (int i = 0; i < letters.length; i++) {
            if (letters[i] == ' ') {
                continue;
            }
            
            if (Character.isDigit(letters[i])) {
                builder.append(letters[i]);
                continue;
            }
            
            if (letters[i] == '.') {
                builder.append(letters[i]);
                continue;
            }
            
            if (contains(letters[i], testCharacters)) {
                addPart(parts, builder);
                parts.add(Character.toString(letters[i]));
            }
        }
        
        addPart(parts, builder);
        
        return parts;
    }

    private void addPart(List<String> parts, StringBuilder builder) {
        if (builder.length() > 0) {
            parts.add(builder.toString());
            builder.delete(0, builder.length());
        }
    }
    
    private boolean contains(char c, String text) {
        for (int i = 0; i < text.length(); i++) {
            char t = text.charAt(i);
            if (c == t) {
                return true;
            }
        }
        
        return false;
    }

    private String toString(List<String> parts) {
        StringBuilder builder = new StringBuilder();
        for (String s : parts) {
            builder.append(s).append(" ");
        }
        return builder.toString().trim();
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接