用限制替换所有非数字

时间:2016-03-29 13:52:56

标签: java regex replaceall

我正在尝试从表达式中提取第一个数字:

这是我的代码:

String[] strArray = input.split("\\+ ");
double[] numbers = getNumbersFromString();

public static double[] getNumbersFromString() {
   double[] numbers = new double[strArray.length];
   for (int i = 0; i < strArray.length; i++) {
            numbers[i] = Double.parseDouble(strArray[i].replaceAll("\\D", ""));
   }

   return numbers;
}

输入及其预期输出:

  • Z = 4x1 + 3x2 + 6x3 // 4 3 6
  • Z = 24x1 + 33x2 + 68x3 // 24 33 68
  • Z = 412x1 + 309x2 + 612x3 // 412 309 612
  • Z = 4329x1 + 3901x2 + 6716x3 // 4329 3901 6716

实际上,它正在移除,但它除了第一个数字之外还检索,第二个也是。例如。(在第一种情况下):// 41 32 63,而它应该只是// 4 3 6.

我可以做类似"\\w = |x\\d", ""的事情,但它只适用于这个特定情况,我想要更一般的事情。

提前致谢。

编辑:

我对原始问题得到了以下答案:

String input = "Z = 4329x1 + 3901x22 + 6716x3";
input = input.replaceAll("^\\D+", "");
double[] numbers = Pattern.compile("x\\d+\\D*")
                      .splitAsStream(input)
                      .mapToDouble(Double::parseDouble)
                      .toArray();

但现在出现了一件新事。在x1/x2/x3 ..或任何类型的“之前没有数字的输入”应该用数字“1”代替。

一些输入及其各自的预期输出:

  • Z = x11 + x2 + x90 // 1 1 1
  • Z = 2x1 + 2x4 + x9 // 2 2 1

顺便说一下,我制作了这个正则表达式:(?<!\d)x\d+

然后我将代码修改为:

return Pattern.compile("x\\d+\\D*")
                .splitAsStream(input.replaceAll("(?<!\\d)x\\d+","1").replaceAll("^\\D+", ""))
                .mapToDouble(Double::parseDouble)
                .toArray();

但它返回给我`java.lang.NumberFormatException:对于输入字符串:“1 + 3”。

PS:它应该适用于新旧案例。

3 个答案:

答案 0 :(得分:3)

这应该按要求运作:

String s = "Z = 4329x1 + 3901x22 + 6716x3";
String[] split = s.replaceAll("^\\D+", "").split("x\\d+\\D*");
System.out.println(Arrays.toString(split)); //[4329, 3901, 6716]

使用流你可以做这样的事情来获得你的双打数组:

String input = "Z = 4329x1 + 3901x22 + 6716x3";
input = input.replaceAll("^\\D+", "");
double[] numbers = Pattern.compile("x\\d+\\D*")
                          .splitAsStream(input)
                          .mapToDouble(Double::parseDouble)
                          .toArray();

修改

要接受x1 + x2之类的表达式,当split返回的字符串为空(并稍微修改正则表达式)时,您可以默认为1

String input = "Z = x1 + x2 + 6716x3";
input = input.replaceAll("^[^x\\d]+", "");
double[] numbers = Pattern.compile("x\\d+[^x\\d]*")
        .splitAsStream(input)
        .mapToDouble(s -> s.isEmpty() ? 1d : Double.parseDouble(s))
        .toArray();

重新编辑

手动在x之前添加缺失的1:

String input = "Z = x1 + x2 + 6716x3 + x4";
input = input.replace(" x", " 1x")
             .replaceAll("^[^x\\d]+", "");

double[] numbers = Pattern.compile("x\\d+[^x\\d]*")
        .splitAsStream(input)
        .mapToDouble(Double::parseDouble)
        .toArray();

答案 1 :(得分:0)

由于您的模式是一个数字后跟x,因此使用positive lookahead就可以了。

正则表达式: \d+(?=x)

<强>解释

  • (?=x)向前看并检查是否存在x。如果是,则匹配\d+

<强> Regex101 Demo

注意:如有必要,请使用双重转义\\d

答案 2 :(得分:0)

你可以在一个正则表达式中进行整个抓取(每行我从你的例子中假设你对你感兴趣的东西) -

(?:=|\+)\s*(\d+)

匹配=+,跳过任何空格,然后捕获数字。使其全球化,它将捕获整行。结果将在捕获组数组中。 (不要好好地讲java,从头到尾告诉你究竟如何)。

Check it here at regex101。 (注意 - 示例一次显示所有行 - 您必须逐个显示它们。)