Оптимальное регулярное выражение для извлечения одного десятичного числа в произвольной строке - PullRequest
0 голосов
/ 09 сентября 2011

Предполагая, что целевая строка, с одной стороны, произвольная, но, с другой стороны, гарантированно содержит одно десятичное число (1 или более цифр), я придумал следующий регулярный шаблон регулярных выражений:

.*?(\d+).*?

Таким образом, если целевой строкой является «(это число 200)», например, Matcher.group(1) будет содержать число.

Существует ли более оптимальный шаблон регулярных выражений (или метод без регулярных выражений) для извлечения этого числа?

Под «оптимальным» я подразумеваю самый быстрый (возможно, с наименьшим количеством циклов ЦП). Только Java.

Ответы [ 2 ]

5 голосов
/ 09 сентября 2011

Просто (\ d +) более чем достаточно.

2 голосов
/ 09 сентября 2011

Я уверен, что regex и parseInt будут работать достаточно хорошо для вас. Однако для вашего интереса я сравнил это с простым циклом.

public static final Pattern DIGITS = Pattern.compile("(\\d+)");

public static void main(String[] args) {
  String text = "Some text before a number 123456 and some after";
  for (int i = 0; i < 5; i++) {
    timeRegex(text);
    timeLooping(text);
  }
}

private static int timeLooping(String text) {
  int ret = 0;
  final int runs = 1000;
  long start = System.nanoTime();
  for (int r = 0; r < runs; r++) {
    for (int i = 0; i < text.length(); i++) {
      char ch = text.charAt(i);
      if (ch <= '9' && ch >= '0')
        ret = ret * 10 + ch - '0';
      else if (ret > 0)
        break;
    }
  }
  long time = System.nanoTime() - start;
  System.out.printf("Took %,d ns to use a loop on average%n", time / runs);
  return ret;
}

private static int timeRegex(String text) {
  int ret = 0;
  final int runs = 1000;
  long start = System.nanoTime();
  for (int r = 0; r < runs; r++) {
    Matcher m = DIGITS.matcher(text);
    if (m.find())
      ret = Integer.parseInt(m.group());
  }
  long time = System.nanoTime() - start;
  System.out.printf("Took %,d ns to use a matcher on average%n", time / runs);
  return ret;
}

печать

Took 19,803 ns to use a matcher on average
Took 85 ns to use a loop on average
Took 12,411 ns to use a matcher on average
Took 83 ns to use a loop on average
Took 8,199 ns to use a matcher on average
Took 79 ns to use a loop on average
Took 11,156 ns to use a matcher on average
Took 104 ns to use a loop on average
Took 4,527 ns to use a matcher on average
Took 94 ns to use a loop on average
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...