在Java开发中,Scanner类常被用来解析各类输入流,默认情况下它会以空白字符作为数据分隔符,将输入内容拆分成多个片段。但实际业务里我们可能需要按照逗号、分号或者更复杂的规则拆分数据,这时候就需要为Scanner类配置正则表达式作为自定义数据分隔符。

Scanner类默认分隔符的问题
Scanner类的默认分隔符是p{javaWhitespace}+code>,也就是匹配一个或多个空白字符,包括空格、制表符、换行符等。如果我们输入的字符串是用逗号分隔的,比如"apple,banana,orange"code>,用默认的Scanner解析就会把整个字符串当成一个完整的token,无法拆分出单个水果名称。
配置正则表达式分隔符的核心方法
Scanner类提供了useDelimiter()code>方法来设置自定义分隔符,该方法可以接收一个字符串形式的正则表达式作为参数,之后Scanner就会按照这个正则规则来拆分输入内容。方法的定义如下:
// 设置Scanner的分隔符为正则表达式 public Scanner useDelimiter(Pattern pattern) // 重载方法,直接传入正则字符串 public Scanner useDelimiter(String pattern)
基础正则分隔符配置示例
如果我们想用逗号作为分隔符,只需要传入逗号的正则表达式即可,示例如下:
import java.util.Scanner;
public class ScannerDelimiterDemo {
public static void main(String[] args) {
// 待解析的输入字符串,用逗号分隔
String input = "apple,banana,orange";
Scanner scanner = new Scanner(input);
// 配置正则分隔符为逗号
scanner.useDelimiter(",");
// 遍历拆分后的所有token
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
scanner.close();
}
}
运行上面的代码,输出结果会是:
apple banana orange
复杂正则分隔符配置示例
如果分隔符不是单一字符,比如输入内容是用逗号或者分号分隔的,就可以用正则的或规则来配置分隔符:
import java.util.Scanner;
public class ComplexDelimiterDemo {
public static void main(String[] args) {
// 输入内容同时包含逗号和分号作为分隔符
String input = "Java;Python,Go;C++";
Scanner scanner = new Scanner(input);
// 配置正则分隔符为逗号或分号,正则中|表示或
scanner.useDelimiter(",|;");
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
scanner.close();
}
}
运行结果如下:
Java Python Go C++
常见注意事项
- 正则表达式中如果需要匹配特殊字符,比如点号、星号等,需要添加转义符,比如想用点号作为分隔符,正则要写成
"\."code>,因为Java字符串里反斜杠本身需要转义。 - 如果正则分隔符匹配到输入的开头或者结尾,Scanner会解析出空字符串的token,比如输入
",apple,banana,"code>,用逗号作为分隔符会解析出四个token,分别是空字符串、apple、banana、空字符串。 - 配置完分隔符后,后续所有的
next()code>、nextInt()code>等读取方法都会按照新的分隔符规则拆分内容,不需要重复配置。
实际场景应用示例
假设我们需要解析一行日志,日志的格式是时间|级别|内容code>,其中时间格式是yyyy-MM-dd HH:mm:ss,我们可以用竖线作为分隔符来拆分日志内容:
import java.util.Scanner;
public class LogParseDemo {
public static void main(String[] args) {
String log = "2024-05-20 14:30:00|INFO|用户登录成功";
Scanner scanner = new Scanner(log);
// 竖线在正则中是特殊字符,需要转义,Java字符串里要写两个反斜杠
scanner.useDelimiter("\|");
String time = scanner.next();
String level = scanner.next();
String content = scanner.next();
System.out.println("时间:" + time);
System.out.println("级别:" + level);
System.out.println("内容:" + content);
scanner.close();
}
}
运行后输出:
时间:2024-05-20 14:30:00 级别:INFO 内容:用户登录成功