Java正则表达式:规范化所有转义或非转义换行符 - 为什么会失败?

时间:2014-07-24 20:52:06

标签: java regex replaceall

我尝试将字符串中的任何换行符或转义换行符规范化为转义的unix换行符。我无法弄清楚为什么这不起作用:

Pattern EOL = Pattern.compile("(\\\\r)?\\\\n|\r?\n");
final String escapedEOL = "\\\\n";

System.out.println(EOL.matcher("asdf\njkl;").replaceAll(escapedEOL));
System.out.println(EOL.matcher("asdf\n").replaceAll(escapedEOL));
System.out.println(EOL.matcher("asdf\r\njkl;").replaceAll(escapedEOL));
System.out.println(EOL.matcher("asdf\r\n").replaceAll(escapedEOL));
System.out.println(EOL.matcher("asdf\\r\\njkl;").replaceAll(escapedEOL));        
System.out.println(EOL.matcher("asdf\\r\\n").replaceAll(escapedEOL));

结果:

asdf\njkl;
asdf

asdf\njkl;
asdf\n
asdf\njkl;
asdf\n
Done

任何人都可以对此有所了解吗? 我意识到我可以把它分成两个电话,但现在我很好奇......

修改: 看起来我应该更加努力地寻找similar problems。在Java 7中看起来应该避免使用具有组的量词。

Pattern EOL = Pattern.compile("\\\\n|\\\\r\\\\n|\r?\n")

也可以。

2 个答案:

答案 0 :(得分:3)

我不确定为什么但正在改变你的正则表达式的顺序似乎可以按你所希望的那样工作,所以改变

Pattern EOL = Pattern.compile("(\\\\r)?\\\\n|\r?\n");

Pattern EOL = Pattern.compile("\r?\n|(\\\\r)?\\\\n");

Demo

无论如何,它看起来更像是bug而不是期望的行为,并且在Java 8中进行了更改,因此您的原始正则表达式也将导致

asdf\njkl;
asdf\n
asdf\njkl;
asdf\n
asdf\njkl;
asdf\n

答案 1 :(得分:1)

|的左侧进行分组似乎可以解决问题:

Pattern EOL = Pattern.compile("((\\\\r)?\\\\n)|\r?\n");