【问题标题】:Java regex: Normalize all escaped or non-escaped newlines - why does this fail?Java regex:规范化所有转义或非转义的换行符 - 为什么会失败?
【发布时间】:2014-07-24 20:52:06
【问题描述】:

我正在尝试将字符串中的任何换行符或转义换行符标准化为转义的 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")

也可以。

【问题讨论】:

  • 我在 Java 8 pastebin.com/wHfvMz01 上得到了不同的结果。
  • 啊,这是Java(TM) SE Runtime Environment (build 1.7.0_45-b18)...不幸的是我不能升级到8。

标签: java regex replaceall


【解决方案1】:

我不知道为什么,但是更改正则表达式中的顺序似乎可以按您的意愿工作,所以更改

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

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

Demo

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

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

【讨论】:

  • 多么奇怪。谢谢,看来我将从现在开始对我在 Java 中使用的任何正则表达式进行三次检查...
  • 很好的故障排除,又一个 Java 正则表达式错误... +1
【解决方案2】:

| 的左侧分组似乎可以使事情正常进行:

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

【讨论】:

  • +1,这也是一种有趣的方法,因为这些外括号在这里应该没有任何意义。
  • @Pshemo 删除可选的? 也使其工作...... \\\\r\\\\n|\r?\n (但 ofc. 改变了含义)。有趣的是,模式失败的用例("asdf\n")实际上应该是模式 right 侧的匹配,但在修改 left 时它会停止匹配i> 交替的一侧。
猜你喜欢
  • 1970-01-01
  • 2011-02-15
  • 2016-12-09
  • 2011-03-02
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
相关资源
最近更新 更多