Поиск регулярного выражения в Java-массиве - PullRequest
13 голосов
/ 21 ноября 2008
ArrayList <String> list = new ArrayList(); 
list.add("behold");
list.add("bend");
list.add("bet");
list.add("bear");
list.add("beat");
list.add("become");
list.add("begin"); 

Есть способ найти regexp bea. * И получить индексы, как в ArrayList.indexOf?

РЕДАКТИРОВАТЬ: возврат предметов в порядке, но мне нужно что-то с большей производительностью, чем линейный поиск

Ответы [ 5 ]

15 голосов
/ 21 ноября 2008

Гермс понял основы правильно. Если вам нужны строки, а не индексы, вы можете улучшить их, используя цикл foreach Java 5:

import java.util.regex.Pattern;
import java.util.ListIterator;
import java.util.ArrayList;

/**
 * Finds the index of all entries in the list that matches the regex
 * @param list The list of strings to check
 * @param regex The regular expression to use
 * @return list containing the indexes of all matching entries
 */
List<String> getMatchingStrings(List<String> list, String regex) {

  ArrayList<String> matches = new ArrayList<String>();

  Pattern p = Pattern.compile(regex);

  for (String s:list) {
    if (p.matcher(s).matches()) {
      matches.add(s);
    }
  }

  return matches
}
8 голосов
/ 21 ноября 2008

Есть ли встроенный метод? Не то, что я знаю из. Тем не менее, это должно быть довольно легко сделать это самостоятельно. Вот некоторый полностью непроверенный код, который должен дать вам основную идею:

import java.util.regex.Pattern;
import java.util.ListIterator;
import java.util.ArrayList;

/**
 * Finds the index of all entries in the list that matches the regex
 * @param list The list of strings to check
 * @param regex The regular expression to use
 * @return list containing the indexes of all matching entries
 */
List<Integer> getMatchingIndexes(List<String> list, String regex) {
  ListIterator<String> li = list.listIterator();

  List<Integer> indexes = new ArrayList<Integer>();

  while(li.hasNext()) {
    int i = li.nextIndex();
    String next = li.next();
    if(Pattern.matches(regex, next)) {
      indexes.add(i);
    }
  }

  return indexes;
}

Возможно, я неправильно использовал части Pattern и ListIterator (я никогда не использовал), но это должно дать основную идею. Вы также можете сделать простой цикл for вместо цикла while над итератором.

4 голосов
/ 21 ноября 2008

Один из вариантов - использовать Apache Commons CollectionUtils метод "select". Вам нужно будет создать объект Predicate (объект с единственным методом «оценки», который использует регулярное выражение для проверки на совпадение и возвращает true или false), а затем вы можете искать элементы в списке, которые соответствуют. Однако он не возвращает индексы, он возвращает коллекцию, содержащую сами элементы.

3 голосов
/ 30 июня 2014

Это один вкладыш в гуаве:

final Iterable<String> matches = Iterables.filter(myStrings, Predicates.contains(Pattern.compile("myPattern")));

for (final String matched : matches) {
   ...
}
1 голос
/ 21 ноября 2008

Я не верю, что есть способ Java API, и Apache Commons не делает этого. Однако не составит труда накатить свой собственный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...