【问题标题】:String replace method is not replacing characters字符串替换方法不替换字符
【发布时间】:2012-09-25 22:18:05
【问题描述】:

我有一个作为字符串传入的句子,我正在替换单词“and”,我想用“”替换它。它并没有用空格替换“和”这个词。下面是我的逻辑的一个例子。当我调试这个时,逻辑确实落入了 sentence.replace。

String sentence = "Define, Measure, Analyze, Design and Verify"
if (sentence.contains("and")){
    sentence.replace("and", " ");
}

这里有什么我遗漏的吗?

【问题讨论】:

  • 字符串是不可变的。

标签: java string replace


【解决方案1】:

当我调试这个时,逻辑确实落入了 sentence.replace。

是的,然后你丢弃返回值。

Java 中的字符串是不可变的 - 当您调用 replace 时,它不会更改 现有 字符串的内容 - 它会返回一个带有修改的 new 字符串.所以你想要:

sentence = sentence.replace("and", " ");

这适用于 所有 String 中的方法(substringtoLowerCase 等)。 没有一个会改变字符串的内容。

请注意,您实际上并不需要在条件下执行此操作 - 毕竟,如果句子 包含 "and",则执行替换不会有任何害处:

String sentence = "Define, Measure, Analyze, Design and Verify";
sentence = sentence.replace("and", " ");

【讨论】:

  • 我不得不打电话给你回答一个重复而不是投票结束。这个问题之前已经被问过很多次了 - 怎么了,乔恩?
  • @MattBall 虽然同意这个问题被反复问过,但我认为这是一个更好的答案,IHMO
  • @MattBall:就像经常发生的那样,我发现给出一个好的、完整的答案比找到一个有好的答案的副本更快。我相信(有些自负,诚然)我在这里的答案比你找到的副本中接受的答案更好,这甚至没有真正的技术意义。 (“您需要使您的字符串实际上等于您对字符串所做的更改” - 什么?)此外,我想指出不需要首先检查包含的方面。
  • 有时间思考这个问题,我觉得这是一个更好的答案。
【解决方案2】:

您没有对replace 的返回值做任何事情。您需要分配方法的结果,即新的String

sentence = sentence.replace("and", " ");

String 在 java 中是不可变的。像replace 这样的方法返回一个新的String

您的contains 测试是不必要的:replace 将在没有个要替换的文本实例时无操作。

【讨论】:

  • 需要我的包含逻辑,因为在某些情况下我不想替换它。逻辑不完全是这样,我只是用这个来举例。
  • @MarkBasler:您提供的示例不需要您的包含逻辑,因此您不应该包含它。好的问题应该只包含展示问题所需的内容 - 通过包含在您提供的情况下毫无意义的代码,您会分散问题的注意力。
  • 我担心包含我担心替换的内容。
  • 顺便把它标记为重复并回答它。保持优雅。
  • 嗨@MarkBasler:我想帮忙。我认为这两个操作没有冲突:您的问题是一个非常常见的问题,一直被问到:java 字符串是不可变的。当我将问题标记为重复时,我试图在此处提高问题和答案的质量,但同时,在留下针对您的问题的特定答案时,我希望为您提供更直接的帮助,具体针对您的示例.您可能会发现 this question on meta 很有用。
【解决方案3】:

你应该重新分配替换的结果,像这样:

 sentence = sentence.replace("and", " ");

请注意String 类是immutable,这意味着它的所有 方法都返回一个新字符串并且从不就地修改原始字符串,因此调用方法的结果在 String 的实例中必须分配给变量或立即使用以使更改生效。

【讨论】:

  • 字符串应该是不可变的,但是 String 库有一些错误,允许您修改原始字符串。
  • @MarkBasler:嗯,你到底在说什么错误?如果您知道字符串是不可变的,那么您根本就不清楚为什么您希望您的代码能够正常工作......
【解决方案4】:

字符串是不可变的,这意味着它们的内容不能改变。当您致电replace(this,that) 时,您最终会得到一个全新的字符串。如果要保留此新副本,则需要将其分配给变量。您可以覆盖旧参考(sentence = sentence.replace(this,that) 或新参考,如下所示:

public class Test{

    public static void main(String[] args) {

        String sentence = "Define, Measure, Analyze, Design and Verify";

        String replaced = sentence.replace("and", "");
        System.out.println(replaced);

    }
}

顺便说一句,请注意我已经删除了contains() 检查,因为这是一个不必要的调用。如果它不包含它,则替换将无法进行任何替换。如果您要替换的内容与您正在检查的实际条件不同,您只需要包含方法。

【讨论】:

  • 这个答案的文字暗示这是导致问题的contains() 调用 - 它不是。这是一个不必要的电话,但实际上并没有引起任何问题。问题是由于忽略了replace的返回值,答案中根本没有解释。
  • @Mr.Jon Skeet 我真的很抱歉,如果答案中的文字暗示相反......但是当我说它不需要时,我的意思是它是不必要的......很好我会将其包含在答案中,使其更加明显.....
  • 如果你这样做会不会更好sentence.replace(" and", ",");
  • @JonSkeet 和其他人 - 我添加了一段实际上解释了正在发生的事情,并将误导性文本移到最后,因为它对于手头的真正问题是相当多余的。
  • @corsiKa:老实说,我不会这样做作为对其他人现有答案的编辑。它极大地改变了答案的含义。
【解决方案5】:
package com.tulu.ds;

public class EmailSecurity {
    public static void main(String[] args) {
        System.out.println(returnSecuredEmailID("sample717@gmail.com"));
    }
    private static String returnSecuredEmailID(String email){
        String str=email.substring(1, email.lastIndexOf("@")-1);
        return email.replaceAll(email.substring(1, email.lastIndexOf("@")-1),replacewith(str.length(),"*"));
    }
    private static String replacewith(int length,String replace) {
        String finalStr="";
        for(int i=0;i<length;i++){
            finalStr+=replace;
        }
        return finalStr;
    }   
}

【讨论】:

  • 请不要只写代码答案,而是解释您的代码如何解决 OP 的问题。 From Review