下面的代码将解析(8,0),(0,-1),(7,-2),(1,1)
字符串,并在迭代时显示值。代码工作正常,但我的想法是,我们可以为整个字符串编写正则表达式,并且我们能够获得像matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), matcher.group(5), matcher.group(6), matcher.group(7), matcher.group(8)
我的代码如下所示
Pattern pattern = Pattern.compile("\\((-?\\d+),(-?\\d+)\\)");
Matcher matcher = pattern.matcher("(8,0),(0,-1),(7,-2),(1,1)");
while (matcher.find()) {
int x = Integer.parseInt(matcher.group(1));
int y = Integer.parseInt(matcher.group(2));
System.out.printf("x=%d, y=%d\n", x, y);
}
答案 0 :(得分:2)
如果您真的想以最快的方式接收八个值,请使用评论中的建议。用空String替换括号。然后用逗号分割整个String并将值转换为整数。
我为你制作了一个基准,向你展示每种方法的速度:
Benchmark Mode Cnt Score Error Units
MyBenchmark.testRegexLoop avgt 30 1232,524 ± 42,972 ns/op
MyBenchmark.testRegexWhole avgt 30 2638,561 ± 59,419 ns/op
MyBenchmark.testReplaceSplit avgt 30 1045,388 ± 66,791 ns/op
重现结果:
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
@Fork(3)
@BenchmarkMode(Mode.AverageTime)
@Measurement(iterations = 10, timeUnit = TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
@Threads(1)
@Warmup(iterations = 5, timeUnit = TimeUnit.NANOSECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {
Blackhole bh = new Blackhole();
@Benchmark
public void testRegexLoop() {
Pattern pattern = Pattern.compile("\\((-?\\d+),(-?\\d+)\\)");
Matcher matcher = pattern.matcher("(8,0),(0,-1),(7,-2),(1,1)");
while (matcher.find()) {
int x = Integer.parseInt(matcher.group(1));
int y = Integer.parseInt(matcher.group(2));
bh.consume(x);
bh.consume(y);
}
}
@Benchmark
public void testRegexWhole() {
Pattern pattern = Pattern
.compile("\\((-?\\d+),(-?\\d+)\\),\\((-?\\d+),(-?\\d+)\\),\\((-?\\d+),(-?\\d+)\\),\\((-?\\d+),(-?\\d+)\\)");
Matcher matcher = pattern.matcher("(8,0),(0,-1),(7,-2),(1,1)");
matcher.find();
bh.consume(Integer.parseInt(matcher.group(1)));
bh.consume(Integer.parseInt(matcher.group(2)));
bh.consume(Integer.parseInt(matcher.group(3)));
bh.consume(Integer.parseInt(matcher.group(4)));
bh.consume(Integer.parseInt(matcher.group(5)));
bh.consume(Integer.parseInt(matcher.group(6)));
bh.consume(Integer.parseInt(matcher.group(7)));
bh.consume(Integer.parseInt(matcher.group(8)));
}
@Benchmark
public void testReplaceSplit() {
String s = "(8,0),(0,-1),(7,-2),(1,1)";
String[] values = s.replaceAll("[()]", "").split(",");
int[] intValues = new int[values.length];
for (int i = 0; i < values.length; i++) {
intValues[i] = Integer.parseInt(values[i]);
}
bh.consume(intValues);
}
}
答案 1 :(得分:1)
要做到这一点,你需要在你的正则表达式中创建所有8个组,就像:
Pattern pattern = Pattern.compile("\\((-?\\d+),(-?\\d+)\\),\\((-?\\d+),(-?\\d+)\\),\\\((-?\\d+),(-?\\d+)\\),\\((-?\\d+),(-?\\d+)\\)");
在这种情况下,您可以调用单个find()并从头到尾获取所有组。但是阅读这样的代码似乎有点困难。如果双打的数量会随时间变化,这将无效。
答案 2 :(得分:1)
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.ArrayList;
import java.util.List;
public class GetNumbers {
public static void main(String[] args) {
String s1 = "(8,0),(0,-1),(7,-2),(1,1)";
String d2 = "[-]?\\d";
List<String> allMatches = new ArrayList<String>();
Matcher m = Pattern.compile(d2).matcher(s1);
while (m.find()) {
allMatches.add(m.group());
}
for (String str : allMatches){
System.out.println(str);
}
}
}
产量
8
0
0
-1
7
-2
1
1
Process finished with exit code 0