【发布时间】:2018-08-10 18:23:26
【问题描述】:
执行摘要:在 Java 的 Scanner 中使用 \R(或其他正则表达式模式)是否有任何警告/已知问题(尤其是关于内部缓冲区的边界条件)?
详情:因为我想对潜在的多平台输入文件进行一些多行模式匹配,所以我使用\R 的模式,根据Pattern javadoc 是:
任何 Unicode 换行序列,都等价于
\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
无论如何,我注意到在我的一个测试文件中,应该解析一个十六进制转储块的循环被缩短了。经过一些调试,我注意到它结束的那一行是 Scanner 内部缓冲区的结尾。
这是我为模拟这种情况而编写的一个测试程序:
public static void main(String[] args) throws IOException {
testString(1);
testString(1022);
}
private static void testString(int prefixLen) {
String suffix = "b\r\nX";
String buffer = new String(new char[prefixLen]).replace("\0", "a") + suffix;
Scanner scanner = new Scanner(buffer);
String pattern = "b\\R";
System.out.printf("=================\nTest String (Len=%d): '%s'\n'%s' found with horizon=0 (w/o bound): %s\n", buffer.length(), convertLineEndings(
buffer), pattern, convertLineEndings(scanner.findWithinHorizon(pattern, 0)));
System.out.printf("'X' found with horizon=1: %b\n", scanner.findWithinHorizon("X", 1) != null);
scanner.close();
}
private static String convertLineEndings(String string) {
return string.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r");
}
...产生此输出(为格式化/简洁而编辑):
=================
Test String (Len=5): 'ab\r\nX'
'b\R' found with horizon=0 (w/o bound): b\r\n
'X' found with horizon=1: true
=================
Test String (Len=1026): 'a ... ab\r\nX'
'b\R' found with horizon=0 (w/o bound): b\r
'X' found with horizon=1: false
对我来说,这看起来像一个错误!我认为扫描仪应该以相同的方式将suffix 与模式匹配,而与它们在输入文本中的显示位置无关(只要prefix 不涉及模式)。 (我还发现了可能相关的Open JDK 错误8176407 和8072582,但这是针对常规Oracle JDK 8u111 的)。
但我可能错过了一些关于扫描器或特定 \R 模式使用的建议(或者 Open JDK 和 Oracle 在这里的相关类有相同的(??)实现?)......因此问题!
【问题讨论】:
-
我不想听起来不欣赏,但这对我没有帮助(因为我已经考虑过扩大视野,但没有选择作为“真正的解决方案”作为这在解析逻辑中可能并不总是一个可行的选择)。我非常感谢您抽出时间来发送答案,但我的问题的要点是 Scanner 不应该根据输入长度(或其内部缓冲区结束/覆盖的内容)采取不同的行动。它仍然可以帮助其他人。这取决于你...
-
这不会是 Java 正则表达式方法中的第一个错误:stackoverflow.com/a/49264884/3600709
标签: java regex java.util.scanner