Java Pattern.splitAsStream 方法
上次修改时间:2025 年 4 月 20 日
splitAsStream 方法是 Java 的 java.util.regex.Pattern 类的一部分。它根据模式匹配拆分输入序列,并返回结果子字符串的流。此方法是在 Java 8 中引入的。
与返回数组的 split 不同,splitAsStream 返回一个 Stream<String>。这使得它非常适合对拆分结果进行函数式风格的处理。对于大型输入,该方法非常高效。
Basic splitAsStream 示例
此示例演示了 splitAsStream 的基本用法。我们将一个简单的逗号分隔字符串拆分成多个部分,并使用流操作处理它们。该模式匹配带有可选空格的逗号。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class BasicSplitAsStream {
public static void main(String[] args) {
String input = "apple, orange, banana, grape";
Pattern pattern = Pattern.compile("\\s*,\\s*");
Stream<String> fruitStream = pattern.splitAsStream(input);
fruitStream.forEach(System.out::println);
}
}
该代码在每个逗号处拆分输入字符串,忽略周围的空格。生成的流包含四个元素:“apple”、“orange”、“banana”和“grape”。我们使用 forEach 打印每个元素。
过滤拆分结果
此示例显示了如何过滤 splitAsStream 的结果。我们拆分包含数字的字符串并过滤掉非数字值。流 API 使此操作简洁明了。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class FilterSplitResults {
public static void main(String[] args) {
String input = "10, 20, thirty, 40, fifty, 60";
Pattern pattern = Pattern.compile("\\s*,\\s*");
pattern.splitAsStream(input)
.filter(s -> s.matches("\\d+"))
.map(Integer::parseInt)
.forEach(System.out::println);
}
}
该代码拆分输入并过滤以仅保留数字字符串。matches 检查确保我们仅处理数字。然后,我们将有效数字转换为整数并打印它们。
处理 CSV 数据
此示例演示了如何使用 splitAsStream 处理 CSV 数据。我们处理带引号的值和引号内的逗号。该模式考虑了 CSV 格式中的这些特殊情况。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class CsvProcessing {
public static void main(String[] args) {
String input = "\"John, Doe\",25,\"New York, NY\",Developer";
Pattern pattern = Pattern.compile(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
pattern.splitAsStream(input)
.map(s -> s.replaceAll("^\"|\"$", ""))
.forEach(System.out::println);
}
}
该模式使用正向预测来处理引号内的逗号。拆分后,我们从每个字段中删除周围的引号。这种方法可以正确处理“John, Doe”和“New York, NY”值。
多行输入处理
此示例显示了如何使用 splitAsStream 处理多行输入。我们将文本拆分为由空行分隔的段落。该模式匹配一个或多个换行符。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class MultilineProcessing {
public static void main(String[] args) {
String input = "First paragraph\n\nSecond paragraph\n\n\nThird paragraph";
Pattern pattern = Pattern.compile("\\n+");
pattern.splitAsStream(input)
.filter(p -> !p.isEmpty())
.forEach(p -> System.out.println("Paragraph:\n" + p + "\n"));
}
}
该代码在换行符序列处拆分输入。我们过滤掉可能由前导或尾随换行符产生的空字符串。然后,用标签打印每个非空段落。
使用 splitAsStream 进行单词拆分
此示例演示了如何使用 splitAsStream 将文本拆分为单词。该模式匹配任何非单词字符序列。我们使用各种流操作处理这些单词。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class WordSplitting {
public static void main(String[] args) {
String input = "The quick brown fox jumps over the lazy dog";
Pattern pattern = Pattern.compile("\\W+");
pattern.splitAsStream(input)
.map(String::toLowerCase)
.distinct()
.sorted()
.forEach(System.out::println);
}
}
该代码在非单词字符序列处将输入拆分为单词。我们将单词转换为小写,使用 distinct 删除重复项,对其进行排序并打印。这展示了将 splitAsStream 与流相结合的强大功能。
处理日志文件
此示例演示了如何使用 splitAsStream 处理日志文件条目。我们将日志字符串拆分为单个日志条目。然后解析每个条目以获取特定信息。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class LogProcessing {
public static void main(String[] args) {
String logs = "[INFO] User logged in\n" +
"[ERROR] Database connection failed\n" +
"[WARN] Disk space low\n" +
"[INFO] User logged out";
Pattern pattern = Pattern.compile("\\n");
pattern.splitAsStream(logs)
.filter(entry -> entry.startsWith("[ERROR]"))
.forEach(System.out::println);
}
}
该代码在换行符处拆分日志字符串。我们过滤以仅保留错误条目并打印它们。这种方法对于将大型日志文件作为流进行处理非常有效。
使用 Lookarounds 进行复杂拆分
此示例显示了使用前瞻和后顾的高级拆分。我们在数字和字母之间的位置拆分字符串。这演示了复杂的拆分场景。
package com.zetcode;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class ComplexSplitting {
public static void main(String[] args) {
String input = "ABC123DEF456GHI789";
Pattern pattern = Pattern.compile("(?<=\\d)(?=\\D)|(?<=\\D)(?=\\d)");
pattern.splitAsStream(input)
.forEach(System.out::println);
}
}
该模式使用后顾和前瞻断言来在数字和非数字字符之间进行拆分。结果是字母和数字交替序列的流。此技术对于解析复杂格式非常有用。
来源
splitAsStream 方法提供了一种使用 Java 的流 API 处理拆分结果的强大方法。它对于大型输入和函数式风格的处理管道特别有用。
作者
列出所有Java教程。