二十、内容输入解析器:Scanner

扫描输入文本内容

一段程序,可以处理很多类型的数据,因此,在程序开始的阶段,必须要有数据源,简单的情况可以是从控制台输入,也可能是从文本读取,亦或者直接定义字符串读取。

在读取文本内容时,如何进行区分各种数据类型呢?因为文本内容均是以字符串存储,若是以字符串读入,那必定需要进行分词,如下代码所示,比较麻烦:

public class test {
    public static BufferedReader input = new BufferedReader(new StringReader("asdjasj 12345 oiw 1.667 wjo ijwq a"));
    
    public static void main(String[] args) {
        String str = input.readLine();
        //分词
        String[] strArray = str.split(" ");
        //分别转换
        String first = strArry[0];
        Integer two = Integer.parseInt(strArray[1]);
        Double three = Double.parseDouble(strArray[3]);
    }
}

Scanner 类

Java SE5 引入了 Scanner 类来简化扫描输入的负担。

首先,Scanner 类可以以 File 对象、InputStream、String对象和Readable对象作为数据源。

其次,定义好了数据源,就要对数据源进行扫描输入,Scanner中有两类扫描方法,并且各自都有对应各种数据类型的读取方法。

分别是 hasNextXxx() 方法和 nextXxx() 方法,前者判断是否存在,后者获取相应数据。

如下方法:

 boolean hasNext(Pattern pattern) 
          下一段文本与模式匹配,则返回 true。 
 boolean hasNext(String pattern) 
          如果下一个文本与指定字符串构造的模式匹配,则返回 true。 
 boolean hasNextBigDecimal() 
          如果下一段文本可以解释一个 BigDecimal,则返回 true。 
 boolean hasNextBigInteger() 
          如果下一段文本可以解释为一个 BigInteger 值,则返回 true。 
boolean hasNextLine() 
          如果在此扫描器的输入中存在另一行,则返回 true。 
--------------我是分割线----------------
 String next() 
          查找并返回来自此扫描器的下一个完整标记。 
 String next(Pattern pattern) 
          如果下一个标记与指定模式匹配,则返回下一个标记。 
 String next(String pattern) 
          如果下一个标记与从指定字符串构造的模式匹配,则返回下一个标记。 
 BigDecimal nextBigDecimal() 
          将输入信息的下一个标记扫描为一个 BigDecimal。 
 BigInteger nextBigInteger() 
          将输入信息的下一个标记扫描为一个 BigInteger。 

此时,该有一个疑问,Scanner 在扫描读取数据的时候,每次读一个 int 或者 String,而实际文本中是一整串的数据,如何区分呢?其实 Scanner 默认是使用一个空格作为分隔符,当然也可以使用下面这个方法来自定义分隔符:

 Scanner useDelimiter(Pattern pattern) 
          将此扫描器的分隔模式设置为指定模式。 
 Scanner useDelimiter(String pattern) 
          将此扫描器的分隔模式设置为从指定 String 构造的模式。 

此外,Scanner 在读取数据时没有抛出异常,而真正 IO 流在读写数据时都强制抛出 IOException 异常,这是因为 Scanner 默认抛出该异常时即为输入结束,也就是它把 IOException 在内部处理掉了,当然也可以通过调用方法找到最近发生的异常进行检查:

IOException ioException() 
          返回此 Scanner 的底层 Readable 最后抛出的 IOException。 

下面举个例子在使用 Scanner,使用正则表达式读取特定文本内容,解析后再输出:

public class test {
    static String data = "58.24.21.52@02/10/2018\n"+
                "58.24.21.52@02/10/2018\n"+
                "58.24.21.52@02/10/2018\n"+
                "58.24.21.52@02/10/2018\n"+
                "58.24.21.52@02/10/2018\n";
                
    public static void main(String[] args) {
        Scanner sc = new Scanner(data);
        String pattern = "(\\d+[.]\\d+[.]\\d+[.]\\d+)@(\\d{2}/\\d{2}/\\d{4}";
        
        While(sc.hasNext(pattern)) {
            sc.next(pattern);
            MatchResult match = sc.match();
            String ip = match.group(1);
            String date = match.group(2);
            
            System.out.format("Threat on %s from %s",date, ip);
        }
    }
}

在使用正则表达式来匹配时,通过方法match()来获得匹配结果对象。这里需要注意一点,每次进行匹配的时候只对下一个分词进行匹配,也就是说如果正则表达式中包含了 Scanner 的分隔符,那就一定无法匹配了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值