替换所有边界和例外

时间:2013-04-16 13:54:12

标签: java regex

我正在尝试使用replaceAll来消除字符串中的所有空格,但两个区域除外。

如果我的字符串是

AB CD #E     F# #GH   I# JK L   M

然后我希望它输出为

ABCD#E     F##GH   I#IJKLM

目前,它正在输出ABCD#EF##GH#IJKLM而不区分#个字符。有没有办法在replaceAll上使用正则表达式?

String s1 = "AB CD #E     F# #GH   I# JK L   M";
s1 = s1.replaceAll("\\s+", "");
System.out.println(s1);

3 个答案:

答案 0 :(得分:3)

我不擅长正则表达式。我将使用循环。

String s1 = "AB CD #E     F# #GH   I# JK L   M";
StringBuilder sb = new StringBuilder();
boolean keepSpace = false;
for(int i = 0; i < s1.length; i++){
    char c = s1.charAt(i);
    if(keepSpace || c != ' ')
        sb.append(c);
    if(c == '#')
        keepSpace = !keepSpace;
}
s1 = sb.toString();
System.out.println(s1);

答案 1 :(得分:3)

您正在寻找replaceAll中基于正则表达式的正面前瞻:

String repl = str.replaceAll("\\s+(?=(?:(?:[^#]*#){2})*[^#]*$)", "");

现场演示:http://ideone.com/nFQhVt

说明:这个正则表达式使用一个正向前瞻,它基本匹配一对文本的0次或多次出现,直到找到一个哈希(#),即([^#]*"){2}在右边空间的每场比赛的手边(RHS)。

简单来说,只有当它位于一对散列符号外时才替换空格,因为散列内的所有匹配在RHS上都会有奇数个[^#]*#匹配。

答案 2 :(得分:1)

尝试

s1 = s1.replaceAll("\\s+(?=(?:[^#]*#[^#]*#)*[^#]*$)", "");

当字符串前面有偶数#时,它只会替换空格 因此它远非万无一失,但它可能已经足够好了 您可以始终首先测试字符串,以确保它包含偶数个#