1. 引言
本文将探讨如何在Java中通过正则表达式(regex)过滤现有列表,创建新列表。我们将学习多种使用Java正则表达式实现列表过滤的方法,并分析不同场景下的最佳实践。
2. 正则表达式基础
正则表达式是用于匹配字符串中特定字符序列的模式。作为多功能工具,它们支持文本过滤、操作、替换和验证等操作。
Java通过java.util.regex
包提供了强大的正则表达式功能支持。
2.1 常用特殊字符
通过组合特殊字符构建匹配模式:
"."
:匹配任意字符(换行符除外)"*"
:匹配前一个字符零次或多次"+"
:匹配前一个字符一次或多次"?"
:匹配前一个字符零次或一次"^"
:匹配字符串开头"$"
:匹配字符串结尾"[]"
:匹配括号内任意字符,如"[abc]"
匹配a
、b
或c
"|"
:逻辑或操作,如"a|b"
匹配a
或b
"()"
:用于分组
2.2 常用正则简写符号
在Java中需使用双反斜杠"\\"
转义特殊字符构造。以下是常用模式的简写符号:
"\\d"
:匹配数字[0-9]
"\\w"
:匹配单词字符[a-zA-Z_0-9]
"\\s"
:匹配空白字符(空格、制表符、换行符)"\\D"
:匹配非数字字符"\\W"
:匹配非单词字符"\\S"
:匹配非空白字符
3. Java中使用正则过滤列表的方法
正则表达式字符串内部会被编译为确定性有限自动机(DFA)或非确定性有限自动机(NFA)。匹配器使用该状态机遍历并匹配输入字符串。
3.1 使用Stream API结合Pattern和Predicate
Java Stream API提供便捷的列表过滤方式,可结合Pattern.compile()
实现正则过滤:
List<String> filterWithStreamPattern() {
List<String> fruits = List.of("apple", "banana", "apricot", "avocado", "berry");
Pattern pattern = Pattern.compile("^a.*");
return fruits.stream()
.filter(pattern.asPredicate())
.toList();
}
此代码筛选以"a"
开头的字符串,返回结果:[apple, apricot, avocado]
。
3.2 使用String.matches()方法
利用String.matches()
方法匹配整个字符串,返回布尔值:
List<String> filterUsingStringMatches() {
List<String> list = List.of("123", "abc", "456def", "789", "xyz");
return list.stream()
.filter(str -> str.matches("\\d+")).toList();
}
创建包含一个或多个数字的新列表,结果为:[123, 789]
。
3.3 结合循环使用Pattern.compile()
对于JDK 8以下版本(无法使用Stream API),可通过循环结合Pattern.matcher()
实现:
List<String> filterUsingPatternCompile() {
List<String> numbers = List.of("one", "two", "three", "four", "five");
List<String> startWithTList = new ArrayList<>();
Pattern pattern = Pattern.compile("^t.*");
for (String item : numbers) {
Matcher matcher = pattern.matcher(item);
if (matcher.matches()) {
startWithTList.add(item);
}
}
return startWithTList;
}
筛选以"t"
开头的字符串,结果为:[two, three]
。
3.4 使用Collectors.partitioningBy()进行条件分组
通过Stream API结合Pattern.compile()
实现条件分组:
Map<Boolean, List<String>> filterUsingCollectorsPartitioningBy() {
List<String> fruits = List.of("apple", "banana", "apricot", "berry");
Pattern pattern = Pattern.compile("^a.*");
return fruits.stream()
.collect(Collectors.partitioningBy(pattern.asPredicate()));
}
筛选以"a"
开头的元素,结果为:
✅ 匹配项(key=true):[apple, apricot]
❌ 未匹配项(key=false):[banana, berry]
4. 结论
本文展示了多种使用正则表达式过滤列表的技术。在众多方案中,Stream API因其可读性和简洁语法脱颖而出。
结合Pattern
和Predicate
的方式尤其高效,特别是在处理大数据集时——因为Pattern
只需编译一次即可重复使用,节省处理时间。
此外,Stream API支持无缝链式操作,性能表现优异。当然,具体场景下也可选择其他方法,但Stream API通常能在代码清晰度和性能之间取得最佳平衡。
⚠️ 踩坑提示:在Java中使用正则时,务必注意字符串中的反斜杠需要双重转义(如"\\d"
而非"\d"
),这是新手常犯的错误。