Java Reference
In-Depth Information
that token. When
hasNext
is invoked it looks past the line separator and
sees that there is something there, so it returns
true
, leaving the cur-
rent input position where it was. When
hasNext(COMMENT)
is invoked, it too
ignores the line separator delimiter and sees a pattern on the next line
that matches the comment, so it also returns
true
, leaving the current
input position where it was. When
nextLine
is invoked its job is to ad-
vance the current position to the beginning of the next line and return
the input that was skipped. The current position is immediately before
the line separator, so moving it after the line separator is a very short
move and, other than the line separator, no input is skipped. Conse-
quently,
nextLine
returns an empty string. In our example this is not
a problem because we loop around again and match the comment a
second time, and this time we remove it properly. However, if your code
assumed that the comment itself was gone after
nextLine
was invoked,
then that assumption would be incorrect. We can fix this problem like
so:
Scanner in = new Scanner(source);
Pattern COMMENT = Pattern.compile("#.*");
String comment;
// ...
while (in.hasNext()) {
if (in.hasNext(COMMENT)) {
comment = in.findWithinHorizon(COMMENT, 0);
in.nextLine();
}
else {
// process other tokens
}
}
Now when
hasNext(COMMENT)
tells us that there is a comment ahead, we
use
findWithinHorizon(COMMENT,0)
to skip the line separator, find the ac-
tual comment, and return it. We don't need to set any horizon because
we know from
hasNext
that the comment is there. After
findWithinHorizon
returns the comment, the current position is just before the line separ-