java scanner 用不了_java Scanner具有神奇的作用可惜大部分java开发人员不知

3. Scanner

有无数 Java 工具能帮助您构建解析器,很多函数语言已成功构建解析器函数库(解析器选择器)。但如果要解析的是逗号分隔值文件,或空格分隔文本文件,又怎么办呢?大多数工具用在此处就过于隆重了,而

String.split() 又不够。(对于正则表达式,请记住一句老话:“ 您有一个问题,用正则表达式解决。那您就有两个问题了。”)

Java 平台的 Scanner 类会是这些类中您最好的选择。以轻量级文本解析器为目标,Scanner 提供了一个相对简单的 API,用于提取结构化文本,并放入强类型的部分。想象一下,如果您愿意,一组类似 DSL 的命令(

源自 Terry Pratchett Discworld 小说)排列在文本文件中,如清单 7:

清单 7. Igor 的任务

fetch 1 head

fetch 3 eye

fetch 1 foot

attach foot to head

attach eye to head

admire  您,或者是本例中称为 Igor的私仆,能轻松使用 Scanner 解析这组违法命令,如清单 8 所示:

清单 8. Igor 的任务,由 Scanner 解析

import java.io.*;

import java.util.*;

public class Igor   implements IPersonalServant

{

public boolean can(String cmd)

{

if (cmd.equals("fetch body parts"))

return true;

if (cmd.equals("attach body parts"))

return true;

else

return false;

}

public void process(File commandFile)  throws FileNotFoundException

{

Scanner scanner = new Scanner(commandFile);  // Commands come in a verb/number/noun or verb form

while (scanner.hasNext())

{

String verb = scanner.next();

if (verb.equals("fetch"))

{

int num = scanner.nextInt();

String type = scanner.next();

fetch (num, type);

}

else if (verb.equals("attach"))

{

String item = scanner.next();

String to = scanner.next();

String target = scanner.next();

attach(item, target);

}

else if (verb.equals("admire"))

{

admire();

}

else

{

System.out.println("I don't know how to "+ verb + ", marthter.");

}

}

}

public void fetch(int number, String type)

{

if (parts.get(type) == null)

{

System.out.println("Fetching " + number + " " + type + (number > 1 ? "s" : "") + ", marthter!");

parts.put(type, number);

}

else

{

System.out.println("Fetching " + number + " more "  + type + (number > 1 ? "s" : "") + ", marthter!");

Integer currentTotal = parts.get(type);

parts.put(type, currentTotal + number);

}

System.out.println("We now have " + parts.toString());

}

public void attach(String item, String target)

{

System.out.println("Attaching the " + item + " to the " +  arget + ", marthter!");

}

public void admire()

{

System.out.println("It'th quite the creathion, marthter");

}

private Map parts = new HashMap();

}   假设 Igor 已在 ServantLoader 中注册,可以很方便地将 can() 调用改得更实用,并重用前面的 Servant 代码,如清单 9 所示:

清单 9. Igor 做了什么

import java.io.*;

import java.util.*;

public class Servant

{

public static void main(String[] args)throws IOException

{

ServiceLoader servantLoader = ServiceLoader.load(IPersonalServant.class);

IPersonalServant i = null;

for (IPersonalServant ii : servantLoader)

if (ii.can("fetch body parts"))

i = ii;

if (i == null)

throw new IllegalArgumentException("No suitable servant found");

for (String arg : args)

{

i.process(new File(arg));

}

}

}

真正 DSL 实现显然不会仅仅打印到标准输出流。我把追踪哪些部分、跟随哪些部分的细节留待给您(当然,还有忠诚的 Igor)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值