Java不匹配。*

时间:2014-09-02 20:09:49

标签: java regex

我在文件中有以下行

00241386002|5296060|0|1|ClaimNote|29DEC2005:10:20:13.557194|JAR007|

我试图与

匹配
line.matches("^\d+\|\d+\|\d+\|\d+.+$")

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

line.matches(".*")

返回false。

任何帮助都将不胜感激。

编辑:

  • 这些行是由缓冲阅读器创建的,因此\r\n将被修剪。
  • 已经尝试过清洁和建造,没有骰子。

答案:

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

1 个答案:

答案 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等其他字符不会被视为行分隔符。)