java - 相对于 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
}
}
我不明白第二个片段与第一个片段有何不同。
根据文档,^
匹配一行的开头,但情况似乎并非如此,因为:
a
在行匹配的开头,a
在输入匹配的开头,并且b
在扫描仪匹配的位置。
如果正则表达式没有相对于扫描仪的位置进行评估,那么它是相对于什么进行评估的?
解决方案
这一切都在那里,只是记录不佳。下面是如何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
}
}
推荐阅读
- ionic4 - Ionic 4 构建后未在平台中创建“ios”文件夹
- fortran - 在 Fortran 中编写混合的 ascii 和二进制数据
- events - 如何在 Modelica 中使用布尔开关来防止库存低于零?
- hanami - 如何使用 Hanami::Repository 在更新/删除命令中使用条件?
- android - 如何在不登录的情况下保存用户值,然后在其他活动的当前用户值中添加数据字段?
- tfs - Mac 上的 tee-clc - 抛出 IllegalArgumentException: update.isFullyPopulated(setFileTimeToCheckin)
- apache - OrientDB 的 DocumentRoot 是什么?或者,OrientDB 的网络文件在哪里?
- java - 有效载荷类型的弹簧卡夫卡模糊方法
- windows - 为什么提交大小有时小于工作集(Windows 内存)
- java - 如何使表格组件中的所有行都拉伸到相同的高度?