用限制替换所有非数字
Replace all non digits with a restriction
我正在尝试从表达式中提取第一个数字:
这是我的代码:
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:它应该适用于新旧案例。
因为你的模式是一个数字后跟一个 x
,所以使用 positive lookahead
这样就可以了。
正则表达式: \d+(?=x)
解释:
(?=x)
向前看并检查 x
是否存在。如果是,则 \d+
匹配。
注意:必要时使用双转义\d
。
这应该按要求工作:
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();
你可以在一个正则表达式中完成整个抓取(我从你的例子中假设你感兴趣的每一行)-
(?:=|\+)\s*(\d+)
它匹配 =
或 +
,跳过任何空格,然后 捕获 数字。使其成为全球性的,它将捕获整行。结果将在捕获组数组中。 (不要说 java 足够好,无法从我的脑海中准确地告诉你。
Check it here at regex101。 (注意 - 示例一次显示所有行 - 您必须一一显示。)
我正在尝试从表达式中提取第一个数字:
这是我的代码:
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:它应该适用于新旧案例。
因为你的模式是一个数字后跟一个 x
,所以使用 positive lookahead
这样就可以了。
正则表达式: \d+(?=x)
解释:
(?=x)
向前看并检查x
是否存在。如果是,则\d+
匹配。
注意:必要时使用双转义\d
。
这应该按要求工作:
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();
你可以在一个正则表达式中完成整个抓取(我从你的例子中假设你感兴趣的每一行)-
(?:=|\+)\s*(\d+)
它匹配 =
或 +
,跳过任何空格,然后 捕获 数字。使其成为全球性的,它将捕获整行。结果将在捕获组数组中。 (不要说 java 足够好,无法从我的脑海中准确地告诉你。
Check it here at regex101。 (注意 - 示例一次显示所有行 - 您必须一一显示。)