微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么“replaceAll”方法不在字符串的开头添加一个空格?

如何解决为什么“replaceAll”方法不在字符串的开头添加一个空格?

我有一个开头、中间和结尾有多个空格的字符串: " Humpty Dumpty sat "

我使用正则表达式 (https://stackoverflow.com/a/2932439/13136767) 删除多余的空格并将其替换为组 1(这是一个空格)。

String str = "        Humpty   Dumpty   sat  ";
str = str.replaceAll("^ +| +$|( )+","$1");
System.out.println("[" + str + "]");

预期输出

[ Humpty Dumpty sat ]

实际输出

[Humpty Dumpty sat]

替换字符串,是在搜索和替换过程中替换每个正则表达式匹配的文本。字符串开头的大空格应该已替换为空格。 为什么不在这里,在字符串的开头添加一个空格?

解决方法

一个简单的解决方案是用一个空白字符替换一系列 multiple 空白字符。

演示:

public class Main {
    public static void main(String args[]) {
        String str = "     Humpty   Dumpty   sat ";
        System.out.println("->" + str + "<-");

        str = str.replaceAll("\\s+"," ");
        System.out.println("->" + str + "<-");
    }
}

输出:

->     Humpty   Dumpty   sat <-
-> Humpty Dumpty sat <-
,

为什么这里没有在字符串的开头添加一个空格?

因为您使用的正则表达式专门设计为不在字符串的开头或结尾添加空格:

str.replaceAll("^ +| +$|( )+","$1");

这里我们有三个选择:^ + +$( )+。所有三个选项都匹配一个或多个空格。区别在于前两个分别只匹配字符串的开头和结尾,只有第三个包含捕获组。因此,如果第三个匹配,即如果空格序列不在字符串的开头或结尾,则 $1 的值将是一个空格。否则为空。

这样做的重点是不要在开头或结尾添加空格。如果您不想要这种行为,则不需要任何这种复杂性。只需用一个空格替换一个或多个空格即可。

,

我不知道你的目标是什么,但如果你只想删除单词之间的多余空格,那么我建议使用环视:

String str = "        Humpty   Dumpty   sat  ";
String output = str.replaceAll("\\b(\\w+)[ ]{2,}(?=\\w)","$1 ");
System.out.println("|" + input + "|");
System.out.println("|" + output + "|");

打印:

|        Humpty   Dumpty   sat  |
|        Humpty Dumpty sat  |
,

replaceAll 执行多次替换时,任何捕获只有在当前替换期间匹配时才可用。无法使用较早或较晚匹配的捕获。

这意味着当字符串开头和结尾的空格被替换时,$1 不可用,因为 ( )+ 交替不匹配。 $1 仅在非锚定交替匹配时出现在字符串中间。

我们可以在一个更简单的例子中看到这一点:

String str = "foobar";
System.out.println(str.replaceAll("(foo)|bar","<$1>")); 

如果 $1 被记住,那么我们希望看到这个输出:

<foo><foo>

虽然不是。实际输出有一个空白,其中 bar 曾经是:

<foo><>

这说明$1匹配后foo清零,替换bar时为空。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。