我注意到以下无法解释的怪异行为:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
var scanner = new Scanner("ab");
System.out.println(scanner.findInLine(".")); // output: a
System.out.println(scanner.findInLine(".")); // output: b
}
}
但是
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
var scanner = new Scanner("ab");
System.out.println(scanner.findInLine(".")); // output: a
System.out.println(scanner.findInLine("^.")); // output: null
}
}
我不明白第二个片段与第一个片段有何不同。
根据the documentation,^
匹配行的开头,但事实并非如此,因为:
a
,a
和b
匹配。如果未对正则表达式进行相对于扫描仪位置的求值,那么相对于正则表达式求值的是什么?
答案 0 :(得分:0)
关于两个代码段,扫描程序仅经过a
,而不是整行。要转到下一行,您需要致电scanner.nextLine()
。
java.util.Scanner
类的findInLine(图案模式)方法 尝试忽略指定模式的下一个出现 定界符。如果在下一个行分隔符之前找到该模式, 扫描仪将前进经过匹配的输入并返回 匹配模式的字符串。如果在 输入直到下一个行分隔符,然后返回null,并且 扫描仪的位置不变。
https://www.geeksforgeeks.org/scanner-findinline-method-in-java-with-examples/
示例:
Scanner scanner = new Scanner("abcde\nx");
System.out.println(scanner.findInLine(".")); // output: a
System.out.println(scanner.findInLine(".")); // output: b
此处扫描程序已与第一个字符(a)匹配,并移至仍位于同一行的b。
Scanner scanner = new Scanner("abcde\nx");
System.out.println(scanner.findInLine(".")); // output: a
scanner.nextLine();
System.out.println(scanner.findInLine(".")); // output: x
在这里,扫描仪的工作方式与以前相同,但我已移过第一行分隔符。
答案 1 :(得分:0)
就在那里,只是文献记载不多。 findInLine
的实现方式如下:
public String findInLine(Pattern pattern) { // omitted: validate parameters // omitted: ensure the internal buffer is large enough return findWithinHorizon(pattern, horizonForLine); }
文档findWithinHorizon
的内容如下:
[...]扫描仪将地平线视为透明的,非固定的边界[...]。
来源:java.util.Scanner#findWithinHorizon(java.util.regex.Pattern,int)
以及锚定范围:
[...]没有锚定边界,此匹配器区域的边界将不匹配诸如
^
和$
之类的锚定。 [...]
这是findWithinHorizon
的实现方式:
public String findWithinHorizon(Pattern pattern, int horizon) { // omitted: validate parameters while (true) { if (findPatternInBuffer(pattern, horizon)) { matchValid = true; return matcher.group(); } // omitted: check if more input is required } return null; }
这是findPatternInBuffer
的实现方式:
private boolean findPatternInBuffer(Pattern pattern, int horizon) { // omitted: calculating search limit matcher.region(position, searchLimit); // omitted: matching pattern }
这就是第二种模式不匹配的原因。正则表达式仅在光标之前搜索,但不认为^
适用于光标位置。但是,它适用于输入的开头,因此第一个模式匹配。
这并不意味着每个带有^
的正则表达式都会失败,后面的正面表情会起作用:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
var scanner = new Scanner("ab");
System.out.println(scanner.findInLine(".")); // output: a
System.out.println(scanner.findInLine("(?<=^.).")); // output: b
}
}