我对代码感到困惑
public class StringReplaceWithEmptyString
{
public static void main(String[] args)
{
String s1 = "asdfgh";
System.out.println(s1);
s1 = s1.replace("", "1");
System.out.println(s1);
}
}
输出是:
asdfgh
1a1s1d1f1g1h1
所以我的第一个意见是String中的每个字符都在两边都有一个空字符串""
。但是,如果'a'
之后的情况(在字符串中),则第二行输出中应该有两个'1'
(一个用于结束' a'和第二个用于开始')。
现在我检查了String是否在这些链接In Java, is a String an array of chars?和String representation in Java中表示为char []我得到了答案为是。
所以我尝试将一个空字符''
分配给char
变量,但它给了我一个编译错误,
无效的字符常量
当我在char[]
char[] c = {'','a','','s'}; // CTE
所以我对三件事情感到困惑。
很抱歉,如果我在问题的任何部分出错了。
答案 0 :(得分:6)
向Tim Biegeleisen回答更多解释。
从Java 8开始,java.lang.String类中的replace
方法的代码是
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
这里你可以清楚地看到字符串被正则表达式模式匹配器替换,而正则表达式“”由零长度字符标识,它存在于任何非零长度字符周围。
因此,在场景后面,您的代码执行如下
Pattern.compile("".toString(), Pattern.LITERAL).matcher("asdfgh").replaceAll(Matcher.quoteReplacement("1".toString()));
输出变为
1a1s1d1f1g1h1
答案 1 :(得分:5)
根据Andy Turner的精彩评论,您对String#replace()
的致电实际上是使用String#replaceAll()
实施的。因此,这里发生了正则表达式替换。匹配发生在第一个字符之前,字符串中每个字符之间以及最后一个字符之后。
^|a|s|d|f|g|h|$
^ this and every pipe matches to empty string ""
您正在进行的比赛是零长度匹配。在String.replaceAll()
中使用的Java的正则表达式实现中,这与上面的示例一样,即匹配每个字符间位置以及第一个字符和最后一个字符之后的位置。
以下是更详细地讨论零长度匹配的参考:http://www.regexguru.com/2008/04/watch-out-for-zero-length-matches/
零宽度或零长度匹配是与任何字符都不匹配的正则表达式匹配。它仅匹配字符串中的位置。例如。正则表达式\ b在1和1,2之间匹配。
答案 2 :(得分:2)
这是因为它传递给你传递给replace()的模式/替换的正则表达式匹配。
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
替换此字符串中与文字目标匹配的每个子字符串 具有指定文字替换序列的序列。该 替换从字符串的开头到结尾,为 例如,替换" aa"用" b"在字符串" aaa"会导致 " BA"而不是" ab"。
参数:
target char值的序列 被替换
替换char值的替换序列
返回:结果字符串
抛出:NullPointerException如果是target 或替换为空。
自: 1.5
请在下面的链接中阅读更多内容...(另请浏览源代码)。
正则表达式,如""将匹配字符串中的每个可能的空字符串。在这种情况下,它恰好是字符串中每个字符的开头和结尾处的每个空格。