【问题标题】:How to parse a Java string into 2 double numbers and eliminate an invalid input?如何将 Java 字符串解析为 2 个双精度数并消除无效输入?
【发布时间】:2021-10-13 23:39:50
【问题描述】:

我正在尝试将应包含 Complex Number 的字符串解析为我编写的 ComplexNumber 类。

字符串应采用以下格式: realNumber+imageNumberi,例如:14-3i

我希望能够:

  1. 识别接收到的字符串是否有效。如果其中有任何不是+-.idigit 的字符,我希望能够抛出异常错误。例如,如果接收到的字符串是13a + 3i

  2. 删除空格(我是使用str.replaceAll 完成的),例如:13 + i

  3. 例如,当我终于有了看起来像 12-3i 的“固定”字符串时,我希望能够将其拆分为 123 的 2 个双精度值。

  4. 如果需要,我还希望能够将 i 更改为 1 或“-1”,例如:-15+i

我读到了regex,所以我尝试使用String.match,但没有成功。 我还成功地提出了一个 50% 可行的解决方案。

这是我尝试这样做的一种方式。 遍历字符串,删除空格,然后遍历每个字符以检查其是否有效。我没有运气,因为它写道:Condition '!Character.isDigit(ch) || ch != '+' || ch != '-'' is always 'true' .

String parsed = str.replaceAll("\\s++", "");

        for(int i = 0; i < parsed.length(); i++) {
            char ch = parsed.charAt(i);
            if (!Character.isDigit(ch) || ch != '+' || ch != '-')
            {
                System.out.println("invalid string.");

            }

我也写试过了

if (!Character.isDigit(ch) || "+-".contains(ch))

if("~#@*+%{}<>[]|\"_^".contains(ch)){

但收到: Required type: CharSequence Provided: char

以下解决方案有效但缺乏:

  • 检查字符串是否有效。
  • 如果之前收到的i 没有值,则将i 更改为1
  • 确定其+- 是图像编号。

代码

String[] splitString = str.split("[+|s+|i]"); // removing spaces, plus sign and "i" from the string

        Double[] complexNumberFields = new Double[2];
        complexNumberFields[0] = Double.parseDouble(splitString[0]);
            complexNumberFields[1] = Double.parseDouble(splitString[1]);
        }
        return new ComplexNumber(complexNumberFields[0], complexNumberFields[1]);

我应该如何在不使用parsermatcher 的情况下以最佳方式实现此功能(因为我还没有阅读它们)。我希望它通过正则表达式和字符串操作来完成。

当然没有使用任何ComplexFormat 方法,因为我正在实现我自己的ComplexNumber 类。

【问题讨论】:

  • 我必须是第一个在这里说正则表达式并不是真正(尽管看起来)构建表达式解析器的合适工具
  • @g00se 我的意思是使用正则表达式来确定字符串是否有效以及是否包含无效字符。
  • @g00se =) 这取决于你将如何使用它 =) (检查我的答案)
  • 立即假设表达式以两位数开头。为什么?

标签: java string parsing string-matching


【解决方案1】:

首先我建议在 Class 中实现这个方法(比如 Integer.valueOf() ex ComplexNumber.valueOf(“14-3i”))

实施价值: 如果您没有任何理由避免它(例如性能),我会使用 regExp 执行此操作,而且您可以使我的 regExp 更加复杂和灵活以涵盖更多情况。我在这里使用 Lombok 来减少类构造噪音(您可以创建构造函数并获取/设置)

另外,请注意,我将 imageNumber 设置为字符串,以防您只需要解析双精度,只需将解析方法或正则表达式(正则表达式变量)更改为 "^(\d{2})\-(\d)[ a-zA-Z]{1}$";

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

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

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ComplexNumber {

    private double realNumber;
    private String imageNumber;


    public static ComplexNumber valueOf(String inputValue) throws Exception {

        final String regex = "^(\\d{2})\\-(\\d[a-zA-Z]{1})$";


        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(inputValue);

        if (matcher.matches()) {
            // constrict the object
            ComplexNumber obj = new ComplexNumber();
            obj.setRealNumber(Double.parseDouble(matcher.group(1)));
            obj.setImageNumber(matcher.group(2));
            return obj;
        } else {
            throw new Exception();
        }

    }

}

【讨论】:

    猜你喜欢
    • 2012-10-21
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多