Java - 使用正则表达式过滤列表条目

23

我的代码长这样:

List<String> filterList(List<String> list, String regex) {
  List<String> result = new ArrayList<String>();
  for (String entry : list) {
    if (entry.matches(regex)) {
      result.add(entry);
    }
  }
  return result;
}

它返回一个仅包含与 regex 匹配的条目的列表。 我在想是否有内置函数可以做到这一点,类似于:

List<String> filterList(List<String> list, String regex) {
  List<String> result = new ArrayList<String>();
  result.addAll(list, regex);
  return result;
}

可以用 List<String>,但要考虑其他类型。 - Wundwin Born
如果有一个获取 Predicate 对象的 add all 方法,那么它应该适用于所有类型。 - Benjy Kessler
3个回答

88

除了Konstantin的回答外:Java 8还通过asPredicatePattern类添加了对Predicate的支持,该方法在内部调用Matcher.find()

Pattern pattern = Pattern.compile("...");

List<String> matching = list.stream()
                            .filter(pattern.asPredicate())
                            .collect(Collectors.toList());

非常棒!


4
这就是答案! :-) 太好了,谢谢分享。因为我懒得一直往下滚动找你的答案,所以我不得不费点力气才能弄清楚 asPredicate 的用法 :-)) - Peter Perháč
很好。是否可以直接获取匹配组,还是需要对收集的List中的每个元素应用Matcher - Eric Duminil
我有这段代码:String regex = "[a-zA-Z]*"; Pattern pattern = Pattern.compile(regex); List<String> matching = list.stream() .filter(Objects::nonNull) .filter(pattern.asPredicate()) .collect(Collectors.toList()); - Mariano Cali

28
在Java 8中,您可以使用新的流API,像以下这样操作:链接
List<String> filterList(List<String> list, String regex) {
    return list.stream().filter(s -> s.matches(regex)).collect(Collectors.toList());
}

哎呀,我正在使用Java 7。 - Benjy Kessler
注意:预编译正则表达式模式可以显著提高过滤性能,尤其是在列表数据较多的情况下!例如:Pattern pattern = Pattern.compile(regex);[...] .filter(s -> pattern.matcher(s).matches()) [...] - t0r0X

4

谷歌的Java库(Guava)有一个接口Predicate<T>,在您的情况下可能非常有用。

static String regex = "yourRegex";

Predicate<String> matchesWithRegex = new Predicate<String>() {
        @Override 
        public boolean apply(String str) {
            return str.matches(regex);
        }               
};

你可以像上面那样定义一个谓词,然后使用一行代码根据该谓词过滤列表:
Iterable<String> iterable = Iterables.filter(originalList, matchesWithRegex);

如果你想将可迭代对象转换为列表,你可以再次使用Guava:

ArrayList<String> resultList = Lists.newArrayList(iterable);

我如何将resultList转换回List<String>?我是否需要在循环中逐个添加它们?这似乎效率低下。 - Benjy Kessler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接