正则表达式在所有标点符号之间添加空格

问题描述:

我需要在字符串中的所有标点符号之间添加空格。正则表达式在所有标点符号之间添加空格

\\ "Hello: World." -> "Hello : World ." 
\\ "It's 9:00?" -> "It ' s 9 : 00 ?" 
\\ "1.B,3.D!"  -> "1 . B , 3 . D !" 

我觉得正则表达式是走,匹配所有非标点符号[a-ZA-Z\\d]+的方式,前添加一个空格和/或后,再提取剩余匹配所有标点符号[^a-ZA-Z\\d]+

但我不知道如何(递归?)调用这个正则表达式。看第一个例子,正则表达式只会匹配"Hello"。我正在考虑通过不断删除和附加匹配正则表达式的第一个实例来构建一个新字符串,而原始字符串不是空的。

private String addSpacesBeforePunctuation(String s) { 
    StringBuilder builder = new StringBuilder(); 
    final String nonpunctuation = "[a-zA-Z\\d]+"; 
    final String punctuation = "[^a-zA-Z\\d]+"; 

    String found; 
    while (!s.isEmpty()) { 

     // regex stuff goes here 

     found = ???; // found group from respective regex goes here 
     builder.append(found); 
     builder.append(" "); 
     s = s.replaceFirst(found, ""); 
    } 

    return builder.toString().trim(); 
} 

然而,这并不觉得自己是正确的方式去...我想我是在复杂的事情......

您可以使用在Java中使用标点符号物业\p{Punct}基于正则表达式lookarounds:

str = str.replaceAll("(?<=\\S)(?:(?<=\\p{Punct})|(?=\\p{Punct}))(?=\\S)", " "); 
  • (?<=\\S)断言,如果上一个字符不是空白
  • (?<=\\p{Punct})断言如果前一个字符是一个标点字符
  • (?=\\p{Punct}) SA位置断言的位置,如果下一个字符是一个标点字符
  • (?=\\S)断言,如果下一个字符是不是一个空白

IdeOne Demo

+1

现在检查我更新的正则表达式。 – anubhava

+1

现在,如果在那里有标点,它会在字符串的末尾添加一个空格。 – RealSkeptic

+0

@RealSkeptic:非常好。我已修复它,检查我更新的正则表达式和演示。 – anubhava

当你看到一个标点符号,你有四种可能性:

  1. 标点符号被空格包围
  2. 标点由空间
  3. 标点后跟一个空格
  4. 标点既不是一个空间,前面和后面之前。

这里是代码,不会正确地替换:

String ss = s 
    .replaceAll("(?<=\\S)\\p{Punct}", " $0") 
    .replaceAll("\\p{Punct}(?=\\S)", "$0 "); 

它使用两个表达式 - 一个匹配的数字2,以及一个相匹配的号码3。由于表达式在彼此的顶部上施加,他们也会照顾到4号。数字1不需要改变。

Demo.