在开发场景中,如有需要从文本中读取指定文本的需求,那么你可能会用上 Scanner 类。
Scanner 类根据空格对文本进行分词,支持整行读取文本或读取指定格式的文本。
先来了解如何定义 Scanner 类及它的几个常见方法。
1.定义 Scanner 类
Scanner 的构造方法可以接收任何类型的输入对象,包括 File 对象、InputStream、String 或者 Readable。
String input = "Sir Robin of Camelot\n22 1.61803";
Scanner scanner = new Scanner(input);
2.nextLine()
读取下一行整行的文本字符串。
3.next()
将下一个分词作为 String 类型读取。
4.hasNextIn()、nextInt()
hasNextIn() 判断下一个分词是否为 int 类型的数据,nextInt() 将下一个分词作为 int 类型返回(若类型转换失败会抛出异常)。
上述两种行为的方法还有支持( byte、short、int、double 、long、BigInteger、BigDecimal )的类型,此处不再赘述。
通过一个简单的例子,来熟悉下基本方法的使用。
public class BetterRead {
public static String input = "Sir Robin of Camelot\n22 1.61803";
public static void main(String[] args) {
Scanner scanner = new Scanner(input);
System.out.println("What is your name?");
String name = scanner.nextLine();
System.out.println("name===" + name);
System.out.println("How old are you? What is favorite double?");
int age = scanner.nextInt();
double favorite = scanner.nextDouble();
scanner.close();
System.out.println("age===" + age);
System.out.println("favorite double===" + favorite);
}
}
What is your name?
name===Sir Robin of Camelot
How old are you? What is favorite double?
age===22
favorite double===1.61803
Scanner 默认根据空格进行分词,但我们可以通过正则表达式指定自己的分隔符。
下述例子中,根据正则表达式扫描:前后均为空白符的 , 进行分割,最终依次读取 int 类型的数字。
public class ScannerDelimiter {
public static void main(String[] args) {
Scanner scanner = new Scanner("12 , 42 , 78 , 99 , 42");
scanner.useDelimiter("\\s*,\\s*");
while (scanner.hasNextInt()){
System.out.println(scanner.nextInt());
}
scanner.close();
}
}
12
42
78
99
42
除此以外,还可以通过正则表达式进行复杂文本类型的扫描,下述例子摘自书中模拟扫描防火墙日志,我们需要提取文本中的 IP 地址和日期信息。
haxNext(String pattern) 可以根据正则表达式的规则校验下一个分词是否满足要求,match() 方法会返回一个 Match 对象,最后根据 Match 类的 group() 方法提取所需要的信息(对 Matcher类感兴趣的朋友可以参考:Matche类在正则表达式中的应用)。
public class ThreatAnalyzer {
public static String threatData = "27.135.15.185@04/08/2008 \n" +
"21.132.25.27@02/08/2008\n" +
"28.152.15.169@03/08/2008\n" +
"20.157.7.125@04/08/2008\n" +
"21.10.8.135@05/08/2008\n" +
"18.10.8.165@06/08/2008";
public static void main(String[] args) {
Scanner scanner = new Scanner(threatData);
String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@" + "(\\d{2}/\\d{2}/\\d{4})";
while (scanner.hasNext(pattern)) {
scanner.next(pattern);
MatchResult match = scanner.match();
String ip = match.group(1);
String date = match.group(2);
System.out.format("Threat on %s from %s \n", date, ip);
}
}
}
Threat on 04/08/2008 from 27.135.15.185
Threat on 02/08/2008 from 21.132.25.27
Threat on 03/08/2008 from 28.152.15.169
Threat on 04/08/2008 from 20.157.7.125
Threat on 05/08/2008 from 21.10.8.135
Threat on 06/08/2008 from 18.10.8.165
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!