3

I am doing an exercise from my book but it only works partially. It works for one of the three words that I want to censor. I have no idea why it works like that. Here is the code:

public static void main(String[] args){
    String text = "Microsoft announced its next generation Java compiler today. It uses advanced parser and special optimizer for the Microsoft JVM.";
    String forbiddenWords = "Java,JVM,Microsoft";
    String[] words = forbiddenWords.split(",");
    String newText = "";
    for(String word: words){
        System.out.println(word);
    }

    for(int i = 0; i < words.length; i++){
        newText = text.replaceAll(words[i], "***");
    }
    System.out.println(newText);
}

And this is what I get for an answer:

*** announced its next generation Java compiler today. It uses advanced parser and special optimizer for the *** JVM.

I also have to censor it with the correct amount of * but I don't know how. I know that I am able to get the count of *s by using words[i].length but I don't know how to utilize it.

tobias_k
  • 81,265
  • 12
  • 120
  • 179

1 Answers1

9

You are not accumulating replacements, but instead assign just the last replacement to newText. Instead of using newText, just assign the new string to the text variable.

for (String word : words) {
    text = text.replaceAll(word, "***");
}
System.out.println(text);

Also, as noted in a comment, be aware that replaceAll actually expects a regular expression, so this might fail, if the strings to be replaced contain any regular expression control characters. Instead, you should just use replace, which will also replace all the matching substrings.

And if you want the number of * to match the length of the word, you can use this technique:

for (String word : words) {
    String xxx = new String(new char[word.length()]).replace("\0", "*");        
    text = text.replace(word, xxx);
}
System.out.println(text);

Output:

********* announced its next generation **** compiler today. It uses advanced parser and special optimizer for the ********* ***.

Speaking of regular expressions, you could in fact also use replaceAll with a regular expression covering all your forbidden words, by replacing the , with a | (provided that those words contain no regex control characters).

String forbiddenWords = "Java,JVM,Microsoft";
text = text.replaceAll(forbiddenWords.replace(',', '|'), "***");
Community
  • 1
  • 1
tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • Oh my god out of frustration I have added a new String that I don't even need. Thank you! I guess I am too tired to spot it. Do you have any idea how to assign the correct amount of *s on a certain word? –  Jan 29 '15 at 20:02
  • @TsvetanDimitrov For repeating characters, see [this question](http://stackoverflow.com/q/1235179/1639625) – tobias_k Jan 29 '15 at 20:05
  • `String asterisks = ""; for(int k = 0; k < word.length(); k++) tmp += "*";``text = text.replaceAll(word, asterisks);` should do it. – Zéychin Jan 29 '15 at 20:06
  • @Zéychin I can't get a thing from this code apart from the String declaring. What's tmp? It's not even declared anywhere. –  Jan 29 '15 at 20:17
  • @tobias_k Yeah but it won't work. Just figured out what it should look like but all it does is it replaces the first word with one * the second with two and the third with three. –  Jan 29 '15 at 20:21
  • Oops! `tmp` was most certainly supposed to be `asterisks`. – Zéychin Jan 29 '15 at 20:28
  • @tobias_k Well the answer seems a bit more than I can take. Looks like a char declared inside the declaration of a String. Anyways I won't try to get it it seems to work. Oh and what is \0 in the replace part. –  Jan 29 '15 at 20:33
  • @TsvetanDimitrov Well, you can also try [any of the other techniques for repeating a character from that question](http://stackoverflow.com/q/1235179/1639625). What this does is: It creates a new char-array of the wanted length, which is initially full of `null` bytes (`\0`), and then replaces those `null` bytes with the actual character. – tobias_k Jan 29 '15 at 20:36