相对于什么是在 java.util.Scanner 中评估的正则表达式?

我注意到以下我无法解释的奇怪行为:


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

  }

}

我不明白第二个片段与第一个片段有何不同。

根据文档^匹配一行的开头,但事实并非如此,因为:

  1. a在行匹配的开头,

  2. a在输入匹配的开头,以及

  3. b在扫描仪匹配的位置。

如果正则表达式不是相对于扫描仪的位置进行评估的,那么它相对于什么进行评估?



慕容708150
浏览 106回答 2
2回答

守候你守候我

关于这两个代码片段,扫描器只是通过了a而不是整行。要转到下一行,您需要调用scanner.nextLine().类的 findInLine(Pattern pattern) 方法java.util.Scanner尝试查找指定模式的下一次出现,忽略定界符。如果在下一个行分隔符之前找到模式,则 扫描器前进到匹配的输入并返回与模式匹配的字符串。如果在直到下一个行分隔符的输入中没有检测到这样的模式,则返回 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在这里,扫描仪的工作方式与以前相同,但我已经移过了第一行分隔符。

Smart猫小萌

一切都在那里,只是记录不完整。以下是findInLine实现方式:public String findInLine(Pattern pattern) {&nbsp; &nbsp; // omitted: validate parameters&nbsp; &nbsp; // omitted: ensure the internal buffer is large enough&nbsp; &nbsp; return findWithinHorizon(pattern, horizonForLine);}来源:java/util/Scanner.java以下是文档必须说明的内容findWithinHorizon:[...] 扫描仪将地平线视为透明的、非锚定的边界 [...]。来源:java.util.Scanner#findWithinHorizon(java.util.regex.Pattern,int)关于锚定边界:[...] 如果没有锚定边界,这个匹配器区域的边界将不会匹配诸如^和 之类的锚点$。[...]来源:java.util.regex.Matcher##useAnchoringBounds(boolean)以下是findWithinHorizon实现方式:public String findWithinHorizon(Pattern pattern, int horizon) {&nbsp; &nbsp; // omitted: validate parameters&nbsp; &nbsp; while (true) {&nbsp; &nbsp; &nbsp; &nbsp; if (findPatternInBuffer(pattern, horizon)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; matchValid = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return matcher.group();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // omitted: check if more input is required&nbsp; &nbsp; }&nbsp; &nbsp; return null;}来源:java/util/Scanner.java以下是findPatternInBuffer实现方式:private boolean findPatternInBuffer(Pattern pattern, int horizon) {&nbsp; &nbsp; // omitted: calculating search limit&nbsp; &nbsp; matcher.region(position, searchLimit);&nbsp; &nbsp; // omitted: matching pattern}java/util/Scanner.java这就是为什么第二个模式不匹配的原因。正则表达式只在光标前搜索,不认为^适用于光标所在位置。但是它适用于输入的开头,因此第一个模式匹配。这并不意味着每个带有的正则表达式^都会失败,后面的正面观察会起作用:import java.util.Scanner;public class Main {&nbsp; public static void main(String[] args) {&nbsp; &nbsp; var scanner = new Scanner("ab");&nbsp; &nbsp; System.out.println(scanner.findInLine("."));&nbsp; &nbsp; &nbsp; &nbsp; // output: a&nbsp; &nbsp; System.out.println(scanner.findInLine("(?<=^.).")); // output: b&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java