java类型扫描器_如何使用Java的扫描器类和正则表达式来标记输入?

“scanner”这个名字有点误导人,因为这个词经常被用来指词法分析器,而这不是scanner的意思。它只是

scanf()

在C、Perl中找到的函数,

. 像StringTokenizer和

split()

,它被设计为向前扫描,直到找到与给定模式匹配的内容,并且不管在路上跳过什么,都会作为令牌返回。

另一方面,词汇分析器必须检查和分类每个字符,即使它只是决定是否可以安全地忽略它们。这意味着,在每次匹配之后,它可以应用几个模式,直到找到一个匹配的模式。

从那一点开始

.否则,它可能会找到序列“//”,并认为它找到了注释的开头,当它确实在字符串文字中,并且没有注意到开头的引号时。

当然,它实际上比这复杂得多,但我只是说明为什么像StringTokenizer这样的内置工具,

分裂()

扫描仪不适合做这种工作。然而,对于有限的词法分析形式,可以使用Java的正则表达式类。事实上,添加scanner类使其更容易,因为添加了新的matcher API来支持它,即区域和

usePattern()

方法。下面是一个在Java ReGEX类之上构建的基本扫描仪的例子。

import java.util.*;

import java.util.regex.*;

public class RETokenizer

{

static List tokenize(String source, List rules)

{

List tokens = new ArrayList();

int pos = 0;

final int end = source.length();

Matcher m = Pattern.compile("dummy").matcher(source);

m.useTransparentBounds(true).useAnchoringBounds(false);

while (pos < end)

{

m.region(pos, end);

for (Rule r : rules)

{

if (m.usePattern(r.pattern).lookingAt())

{

tokens.add(new Token(r.name, m.start(), m.end()));

pos = m.end();

break;

}

}

pos++; // bump-along, in case no rule matched

}

return tokens;

}

static class Rule

{

final String name;

final Pattern pattern;

Rule(String name, String regex)

{

this.name = name;

pattern = Pattern.compile(regex);

}

}

static class Token

{

final String name;

final int startPos;

final int endPos;

Token(String name, int startPos, int endPos)

{

this.name = name;

this.startPos = startPos;

this.endPos = endPos;

}

@Override

public String toString()

{

return String.format("Token [%2d, %2d, %s]", startPos, endPos, name);

}

}

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

{

List rules = new ArrayList();

rules.add(new Rule("WORD", "[A-Za-z]+"));

rules.add(new Rule("QUOTED", "\"[^\"]*+\""));

rules.add(new Rule("COMMENT", "//.*"));

rules.add(new Rule("WHITESPACE", "\\s+"));

String str = "foo //in \"comment\"\nbar \"no //comment\" end";

List result = RETokenizer.tokenize(str, rules);

for (Token t : result)

{

System.out.println(t);

}

}

}

顺便说一句,这是我发现的唯一一个很好的用途

lookingAt()

方法。D

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值