我在文件中有以下行
00241386002|5296060|0|1|ClaimNote|29DEC2005:10:20:13.557194|JAR007|
我试图与
匹配line.matches("^\d+\|\d+\|\d+\|\d+.+$")
该模式适用于文件中之前约10k左右的行。它也适用于前一行,它在时间戳上是相同的。但是,它不适用于该行。甚至
line.matches(".*")
返回false。
任何帮助都将不胜感激。
编辑:
\r
和\n
将被修剪。答案:
答案 0 :(得分:5)
\d+\|\d+\|\d+\|\d+
正则表达式的一部分似乎工作正常,这表明问题必须与.*
部分相关。
让我们通过匹配.
默认测试哪些字符可以阻止matches
返回true
。
(我将只测试范围0
- FFFF
中的字符,但Unicode有更多字符 - 比如代理对 - 所以我不是说这些只是.
可以&#的字符39;匹配 - 即使是今天我们也无法确定未来。
for (int ch = 0; ch < '\uFFFF'; ch++) {
if (!Character.toString((char)ch).matches(".*")) {
System.out.format("%-4d hex: \\u%04x %n", ch, ch);
}
}
我们将得到结果(添加一些评论和链接)
10 hex: \u000a
- 换行(\ n)
13 hex: \u000d
- 回车(\ r)
133 hex: \u0085
- 下一行(NEL)
8232 hex: \u2028
- 行分隔符
8233 hex: \u2029
- 段落分隔符
所以我怀疑你的字符串包含其中一个字符。现在,并非所有工具都将这些字符正确识别为正确的行分隔符(正则表达式识别)。例如,让我们测试BufferedReader
String data = "AAA\nBBB\rCCC\u0085DDD\u2028EEE\u2029FFF";
BufferedReader br = new BufferedReader(new StringReader(data));
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
}
我们得到了结果:
AAA BBB CCCDDD EEE FFF ⬑ here we have `\u0085` (NEL)
如您所见,不基于正则表达式引擎的工具可以返回表示单行的字符串,但仍将包含正则表达式作为行分隔符的字符。
我们可以尝试让.
匹配任何字符。为此,我们可以使用Pattern.DOTALL
标记(我们也可以通过在(?s)
等正则表达式中添加(?s).*
来启用它。)
同样already mention your question,我们可以在Pattern.UNIX_LINES
模式((?d)
标志)中设置正则表达式引擎,这样只会将\n
视为行分隔符(\r
等其他字符不会被视为行分隔符。)