概述
Scanner
Scanner sc1 = new Scanner(System.in);
private Scanner(Readable source, Pattern pattern) {
//-确定源和分割模式非空
断言,判断一个条件是否为真,否则报错
assert source != null : "source should not be null";
assert pattern != null : "pattern should not be null";
//传入输入流
this.source = source;
//传入分隔令牌模式
delimPattern = pattern;
//传入一个容量为BUFFER_SIZE(默认1024字节)的CharBuffer对象
buf = CharBuffer.allocate(BUFFER_SIZE);
//传入limit=0;Invariants: mark <= position <= limit <= capacity
buf.limit(0);
//传入用分隔模式匹配字符缓存的匹配器
matcher = delimPattern.matcher(buf);
//设置匹配器可跨边界检验匹配是否正确
matcher.useTransparentBounds(true);
//匹配器不对区域边界进行铆钉
matcher.useAnchoringBounds(false);
//传入默认的语言环境下的格式化日期、数字和货币
useLocale(Locale.getDefault(Locale.Category.FORMAT));
}
String s2=sc1.next();
读取数据至buf,匹配分隔模式,返回之间的内容
//-读取数据至buf,匹配分隔模式,返回之间的内容
查找并返回此扫描程序中的下一个完整令牌。
匹配分隔模式,返回之间的内容
public String next() {
//确保未关闭
ensureOpen();
//清理规则缓存和类型缓存 hasNextPattern = null;typeCache = null;
clearCaches();
while (true) {
@1 若准备工作完成,获取完整令牌
String token = getCompleteTokenInBuffer(null);
if (token != null) {
matchValid = true;
skipped = false;
return token;
}
if (needInput)
//从source中读取buf大小的数据
readInput();
else
throwFor();
}
}
@1
//-获取被delims包围的令牌
返回与指定模式匹配的“完整标记”
如果被delims包围,则令牌完成; 部分令牌
以delims为前缀但不是由它们加后缀
该位置前进到该完整令牌的末尾
Pattern == null表示完全接受任何令牌
三重return:
1.有效字符串表示已找到
2.使用needInput = false的null意味着我们永远找不到它
3.使用needInput = true的null表示在readInput之后再次尝试
Scanner#
private String getCompleteTokenInBuffer(Pattern pattern) {
//设置匹配结果不可用
matchValid = false;
//-首先跳过delim
//Skip delims first
//设置matcher的parentPattern为delimPattern
matcher.usePattern(delimPattern);
//判断此次操作是否还未被跳过delims
if (!skipped) { // Enforcing only one skip of leading delims
//仅强制执行前导delim的一次跳过
//设定matcher匹配区域,默认from=0,end=0
matcher.region(position, buf.limit());
//尝试将从区域开头开始的输入序列与模式匹配。
if (matcher.lookingAt()) {
// If more input could extend the delimiters then we must wait
// for more input
//-如果更多的输入可以扩展分隔符,那么我们必须等待
//获得更多输入
if (matcher.hitEnd() && !sourceClosed) {
needInput = true;
return null;
}
// The delims were whole and the matcher should skip them
skipped = true;
position = matcher.end();
}
}
// Must look for next delims. Simply attempting to match the
// pattern at this point may find a match but it might not be
// the first longest match because of missing input, or it might
// match a partial token instead of the whole thing.
//-必须寻找下一个delims。 只是试图匹配
//此时的模式可能会找到匹配但可能不匹配
//由于缺少输入而导致的第一个最长匹配,或者可能
//匹配部分令牌而不是整个事物。
// Then look for next delims
matcher.region(position, buf.limit());
boolean foundNextDelim = matcher.find();
if (foundNextDelim && (matcher.end() == position)) {
// Zero length delimiter match; we should find the next one
// using the automatic advance past a zero length match;
// Otherwise we have just found the same one we just skipped
foundNextDelim = matcher.find();
}
if (foundNextDelim) {
// In the rare case that more input could cause the match
// to be lost and there is more input coming we must wait
// for more input. Note that hitting the end is okay as long
// as the match cannot go away. It is the beginning of the
// next delims we want to be sure about, we don't care if
// they potentially extend further.
if (matcher.requireEnd() && !sourceClosed) {
needInput = true;
return null;
}
int tokenEnd = matcher.start();
// There is a complete token.
if (pattern == null) {
// Must continue with match to provide valid MatchResult
pattern = FIND_ANY_PATTERN;
}
//
Attempt to match against the desired pattern
matcher.usePattern(pattern);
matcher.region(position, tokenEnd);
@2
if (matcher.matches()) {
@3
String s = matcher.group();
position = matcher.end();
return s;
} else { // Complete token but it does not match
return null;
}
}
// If we can't find the next delims but no more input is coming,
// then we can treat the remainder as a whole token
if (sourceClosed) {
if (pattern == null) {
// Must continue with match to provide valid MatchResult
pattern = FIND_ANY_PATTERN;
}
// Last token; Match the pattern here or throw
matcher.usePattern(pattern);
matcher.region(position, buf.limit());
if (matcher.matches()) {
String s = matcher.group();
position = matcher.end();
return s;
}
// Last piece does not match
return null;
}
// There is a partial token in the buffer; must read more
// to complete it
needInput = true;
return null;
}
@2
public boolean matches() {
return match(from, ENDANCHOR);
}
boolean match(int from, int anchor) {
this.hitEnd = false;
this.requireEnd = false;
from = from < 0 ? 0 : from;
this.first = from;
this.oldLast = oldLast < 0 ? from : oldLast;
for (int i = 0; i < groups.length; i++)
groups[i] = -1;
acceptMode = anchor;
boolean result = parentPattern.matchRoot.match(this, from, text);
if (!result)
this.first = -1;
this.oldLast = this.last;
return result;
}
@3
String s = matcher.group();
Matcher#
public String group() {
return group(0);
}
public String group(int group) {
if (first < 0)
throw new IllegalStateException(“No match found”);
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
//存放匹配值的索引数组
if ((groups[group2] == -1) || (groups[group2+1] == -1))
return null;
//获取匹配组在输入文本上的索引,并截取出对应的字符序列
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
CharSequence getSubSequence(int beginIndex, int endIndex) {
return text.subSequence(beginIndex, endIndex);
}
最后
以上就是激情篮球为你收集整理的java-scanner源码杂谈Scanner的全部内容,希望文章能够帮你解决java-scanner源码杂谈Scanner所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复