Java不匹配.*

Kev*_*vin 5 java regex

我在文件中有以下行

00241386002|5296060|0|1|ClaimNote|29DEC2005:10:20:13.557194|JAR007|
Run Code Online (Sandbox Code Playgroud)

我想要配合

line.matches("^\d+\|\d+\|\d+\|\d+.+$")
Run Code Online (Sandbox Code Playgroud)

该模式适用于文件中先前约10k左右的行.它也适用于前一行,它在时间戳上是相同的.但是,它不适用于该行.甚至

line.matches(".*")
Run Code Online (Sandbox Code Playgroud)

返回false.

任何帮助,将不胜感激.

编辑:

  • 该线由缓冲读取器创建的,所以\r\n将被修剪.
  • 已经尝试过清洁和建造,没有骰子.

回答:

  • 感谢Pshemo在第一条评论中的回答.(?d).*(unix模式)也有效.在行的末尾有一个'\ u0085',缓冲的阅读器没有修剪但是Pattern被认为是行终止符.

Psh*_*emo 5

问题

\d+\|\d+\|\d+\|\d+你的正则表达式的一部分似乎工作正常,这表明问题必须与.*部分相关.

让我们测试默认情况下哪些字符不能匹配哪些字符可以.防止matches返回true.
(我将只测试范围内的字符0- FFFF但Unicode有更多的字符 - 比如代理对 - 所以我不是说这些只是.无法匹配的字符 - 即使它是今天我们无法确定未来) .

for (int ch = 0; ch < '\uFFFF'; ch++) {
    if (!Character.toString((char)ch).matches(".*")) {
        System.out.format("%-4d hex: \\u%04x %n", ch, ch);
    }
}
Run Code Online (Sandbox Code Playgroud)

我们将得到结果(添加一些评论和链接)

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);
}
Run Code Online (Sandbox Code Playgroud)

我们得到的结果是:

AAA
BBB
CCCDDD?    EEE?    FFF
   ? here we have `\u0085` (NEL) 

如您所见,不基于正则表达式引擎的工具可以返回表示单行的字符串,但仍将包含正则表达式作为行分隔符的字符.

可能的解决方案

我们可以尝试.匹配任何角色.为此,我们可以使用Pattern.DOTALLflag(我们也可以通过添加(?s)regex 来启用它(?s).*).

另外,正如您已经提到过的问题,我们可以在Pattern.UNIX_LINES模式((?d)标志)中设置正则表达式引擎,这将使其仅\n作为行分隔符(其他字符\r不会被视为行分隔符).