整个字符串的正则表达式

时间:2015-09-15 04:08:35

标签: java regex

下面的代码将解析(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);
}

3 个答案:

答案 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