349

I can use this:

String str = "TextX Xto modifyX";
str = str.replace('X','');//that does not work because there is no such character ''

Is there a way to remove all occurrences of character X from a String in Java?

I tried this and is not what I want: str.replace('X',' '); //replace with space

Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
evilReiko
  • 19,501
  • 24
  • 86
  • 102

13 Answers13

570

Try using the overload that takes CharSequence arguments (eg, String) rather than char:

str = str.replace("X", "");
Erick Robertson
  • 32,125
  • 13
  • 69
  • 98
LukeH
  • 263,068
  • 57
  • 365
  • 409
  • 2
    First argument is regular expression, sometimes it won't work as expected, especially if this string comes from user input. – vbezhenar Jul 04 '12 at 08:50
  • 9
    @vsb: Not true. Both arguments of that particular overload are `CharSequence`. http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace%28java.lang.CharSequence,%20java.lang.CharSequence%29 – LukeH Jul 04 '12 at 09:10
  • What to do in case the `X` is of type char? – KNU Mar 06 '14 at 06:46
  • 7
    @Kunal: I guess you'd need to [`toString`](http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#toString%28%29) it first. So your code would look something like `str = str.replace(yourChar.toString(), "");` – LukeH Mar 06 '14 at 10:01
  • Note you can use unicode escapes, e.g. no remove noncharacters `str = str.replace("\uffff", "");` – Jaime Hablutzel May 16 '14 at 02:34
  • `replace` really uses `Pattern`, but with `LITERAL` flag. It can become overhead. – cybersoft Apr 11 '16 at 17:54
  • Weird i get Call to undefined function replace() – Michael Rogers Apr 19 '18 at 20:14
  • First argument of `replace()` is of type `CharSequence` and is used as argument for a `Pattern.compile()`-call that generates the RegEx. – Kaplan Oct 02 '19 at 22:24
  • This answer is the most simple and shortest but, if performance is important, then another implementation should be used. I provided an answer that performs a quick benchmark of the 3 main styles of answers, including this one. – Volksman Nov 19 '19 at 21:58
  • String#replaceAll() uses regex; String#replace() doesn't. – NomadMaker Dec 10 '20 at 23:06
47

Using

public String replaceAll(String regex, String replacement)

will work.

Usage would be str.replace("X", "");.

Executing

"Xlakjsdf Xxx".replaceAll("X", "");

returns:

lakjsdf xx
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Michael Wiles
  • 20,902
  • 18
  • 71
  • 101
  • 6
    Regex is probably overkill for this unless you're restricted to supporting Java 1.4 - since version 1.5 there's a `replace` overload that takes a simple `CharSequence`. – LukeH Jan 01 '11 at 23:59
  • 3
    @LukeH, This is the decompiled source to String.replace. It's using regex. I agree that it regex feels heavy, but that's what is under the hood even for the accepted answer above. public String replace(CharSequence var1, CharSequence var2) { return Pattern.compile(var1.toString(), 16).matcher(this).replaceAll(Matcher.quoteReplacement(var2.toString())); } – Perry Tew Jun 20 '16 at 12:33
  • 1
    Thankfully, that is not true anymore. It does not use regex anymore. – Nand Aug 17 '20 at 16:12
29

If you want to do something with Java Strings, Commons Lang StringUtils is a great place to look.

StringUtils.remove("TextX Xto modifyX", 'X');
Arend v. Reinersdorff
  • 4,110
  • 2
  • 36
  • 40
  • 1
    exactly what I looked for, probably because it just looks more clear than `replace`. – Line Sep 21 '19 at 18:52
6
String test = "09-09-2012";
String arr [] = test.split("-");
String ans = "";

for(String t : arr)
    ans+=t;

This is the example for where I have removed the character - from the String.

Tiago Almeida
  • 14,081
  • 3
  • 67
  • 82
JavaChamp
  • 77
  • 1
  • 1
3

Hello Try this code below

public class RemoveCharacter {

    public static void main(String[] args){
        String str = "MXy nameX iXs farXazX";
        char x = 'X';
        System.out.println(removeChr(str,x));
    }

    public static String removeChr(String str, char x){
        StringBuilder strBuilder = new StringBuilder();
        char[] rmString = str.toCharArray();
        for(int i=0; i<rmString.length; i++){
            if(rmString[i] == x){

            } else {
                strBuilder.append(rmString[i]);
            }
        }
        return strBuilder.toString();
    }
}
Ankush soni
  • 1,439
  • 1
  • 15
  • 30
Raju
  • 49
  • 4
2

I like using RegEx in this occasion:

str = str.replace(/X/g, '');

where g means global so it will go through your whole string and replace all X with ''; if you want to replace both X and x, you simply say:

str = str.replace(/X|x/g, '');

(see my fiddle here: fiddle)

Gerrit B
  • 184
  • 1
  • 9
  • I guess this might work, but the correct answer executes faster and shorter, it's always better to avoid RegEx as much as possible as it's known to be slower than other methods – evilReiko Sep 17 '13 at 10:45
2

Use replaceAll instead of replace

str = str.replaceAll("X,"");

This should give you the desired answer.

Ayushi Jain
  • 828
  • 8
  • 17
  • 1
    replace ends up using replaceAll. Look into the implementation. This is how String#replace is implemented: `return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString()));` – Molasses Jun 27 '18 at 19:14
2

Evaluation of main answers with a performance benchmark which confirms concerns that the current chosen answer makes costly regex operations under the hood

To date the provided answers come in 3 main styles (ignoring the JavaScript answer ;) ):

  • Use String.replace(charsToDelete, ""); which uses regex under the hood
  • Use Lambda
  • Use simple Java implementation

In terms of code size clearly the String.replace is the most terse. The simple Java implementation is slightly smaller and cleaner (IMHO) than the Lambda (don't get me wrong - I use Lambdas often where they are appropriate)

Execution speed was, in order of fastest to slowest: simple Java implementation, Lambda and then String.replace() (that invokes regex).

By far the fastest implementation was the simple Java implementation tuned so that it preallocates the StringBuilder buffer to the max possible result length and then simply appends chars to the buffer that are not in the "chars to delete" string. This avoids any reallocates that would occur for Strings > 16 chars in length (the default allocation for StringBuilder) and it avoids the "slide left" performance hit of deleting characters from a copy of the string that occurs is the Lambda implementation.

The code below runs a simple benchmark test, running each implementation 1,000,000 times and logs the elapsed time.

The exact results vary with each run but the order of performance never changes:

Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms

The Lambda implementation (as copied from Kaplan's answer) may be slower because it performs a "shift left by one" of all characters to the right of the character being deleted. This would obviously get worse for longer strings with lots of characters requiring deletion. Also there might be some overhead in the Lambda implementation itself.

The String.replace implementation, uses regex and does a regex "compile" at each call. An optimization of this would be to use regex directly and cache the compiled pattern to avoid the cost of compiling it each time.

package com.sample;

import java.util.function.BiFunction;
import java.util.stream.IntStream;

public class Main {

    static public String deleteCharsSimple(String fromString, String charsToDelete)
    {
        StringBuilder buf = new StringBuilder(fromString.length()); // Preallocate to max possible result length
        for(int i = 0; i < fromString.length(); i++)
            if (charsToDelete.indexOf(fromString.charAt(i)) < 0)
                buf.append(fromString.charAt(i));   // char not in chars to delete so add it
        return buf.toString();
    }

    static public String deleteCharsLambda(String fromString1, String charsToDelete)
    {
        BiFunction<String, String, String> deleteChars = (fromString, chars) -> {
            StringBuilder buf = new StringBuilder(fromString);
            IntStream.range(0, buf.length()).forEach(i -> {
                while (i < buf.length() && chars.indexOf(buf.charAt(i)) >= 0)
                    buf.deleteCharAt(i);
            });
            return (buf.toString());
        };

        return deleteChars.apply(fromString1, charsToDelete);
    }

    static public String deleteCharsReplace(String fromString, String charsToDelete)
    {
        return fromString.replace(charsToDelete, "");
    }


    public static void main(String[] args)
    {
        String str = "XXXTextX XXto modifyX";
        String charsToDelete = "X";  // Should only be one char as per OP's requirement

        long start, end;

        System.out.println("Start simple");
        start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++)
            deleteCharsSimple(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));

        System.out.println("Start lambda");
        start = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++)
            deleteCharsLambda(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));

        System.out.println("Start replace");
        start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++)
            deleteCharsReplace(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));
    }
}
Volksman
  • 1,969
  • 23
  • 18
  • If the lambda function is called as it is intended to do, the timing is the following _(nobody wraps a lambda function into a member function)_. Furthermore Your deleteCharsReplace() is wrong implemented: it replaces one String "XYZ" and not as required 'X','Y' and 'Z' what `fromString.replace("X", "").replace("Y", "").replace("Z", "");` would need. Now we get the correct timing: Start simple Time: 759 | Start lambda Time: **1092** | Start deleteCharsLambda() Time: 1420 | Start replace corrected Time: **4636** – Kaplan Nov 20 '19 at 11:11
  • "nobody wraps a lambda function into a member function" - except for the purpose of calling it in a benchmark scenario so that it is consistent with the way the other implementations are called. – Volksman Nov 21 '19 at 22:10
  • I just realized that the OP asked about removing all occurrences of a *single* character but your answer changed the scope to deal with a set of characters. The "accepted" answer implementation that I used does not and was never intended to cater for multiple characters. So I have updated the above benchmark to reflect this and the benchmark times. BTW if you want to increase the scope to support multiple characters calling replace multiple times is costly. Better to switch to a single call to replaceAll("[XYZ]", "") – Volksman Nov 21 '19 at 22:26
  • The function as shown in the [solution](https://stackoverflow.com/questions/4576352/remove-all-occurrences-of-char-from-string/56916146#56916146) is only inited once when called. To wrap the function definiton additionally to the function call into the member function has the only effect to distort the benchmark. – Kaplan Nov 22 '19 at 13:06
  • It's virtually impossible to properly benchmark quick duration methods by making a single call as the variance of each call is so high. So benchmarking normally involves many repeated calls to the same method and then total time is evaluated to compare with total times of the alternatives (or to calculate an average if required).. – Volksman Nov 24 '19 at 21:29
  • In normal usage a method like this would be at the end of a long chain of method calls e.g. processing millions of records from a file, for example, and performing this step is just one stage in the processing of each record so it will definitely be called from another method and not directly inline in some single "huge looping mega method" (anti pattern) that initializes it once at the start. All implementations were tested via an external method call to emulate this. If one were to precompile and cache the chosen answer's pattern and reuse its matcher then it would also be much faster. – Volksman Nov 24 '19 at 21:32
1

You will need to put the characters needs to be removed inside the square brackets during the time of replacement. The example code will be as following:

String s = "$116.42".replaceAll("[$]", "");
Arefe
  • 11,321
  • 18
  • 114
  • 168
0

here is a lambda function which removes all characters passed as string

BiFunction<String,String,String> deleteChars = (fromString, chars) -> {
  StringBuilder buf = new StringBuilder( fromString );
  IntStream.range( 0, buf.length() ).forEach( i -> {
    while( i < buf.length() && chars.indexOf( buf.charAt( i ) ) >= 0 )
      buf.deleteCharAt( i );
  } );
  return( buf.toString() );
};

String str = "TextX XYto modifyZ";
deleteChars.apply( str, "XYZ" ); // –> "Text to modify"

This solution takes into acount that the resulting String – in difference to replace() – never becomes larger than the starting String when removing characters. So it avoids the repeated allocating and copying while appending character-wise to the StringBuilder as replace() does.
Not to mention the pointless generation of Pattern and Matcher instances in replace() that are never needed for removal.
In difference to replace() this solution can delete several characters in one swoop.

Kaplan
  • 2,572
  • 13
  • 14
  • 1
    Lambdas/Functional Programming is very hip right now but using it to create a solution that is 10x longer than the chosen answer can't be justified IMHO, hence the down vote. – Volksman Nov 18 '19 at 06:17
  • `str.replace("…", "")` instantiates `private Pattern(…)` and then on the generated pattern calls `public String replaceAll(String repl)`. So the following function-calls happened: `return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString()));` – see Sal_Vader_808 comment. All in all c.a. 3 times longer than my _hip_ lambda solution. And here it is nicely explained why my _hip_ lambda solution is also faster: [Why is Java's String::replace() so slow?](https://www.cqse.eu/en/blog/string-replace-performance/) – Kaplan Nov 18 '19 at 15:59
  • _in own thing_: If it were really about the size of the solution, some other solutions twice as big or the solutions that require an external library would be more suitable candidates for criticism. A language extension that has been part of the language for years since Java 8 is not really _hip_. A general problem with the scoring system is, that the time factor weighs more heavily than the quality of a solution. As a result, the more up-to-date and sometimes even better solutions are increasingly being found in the back third. – Kaplan Nov 19 '19 at 13:38
  • I was referring to 10x longer in terms of code not execution speed. Anything that compiles a regex pattern each time it's called can be much slower. You would really need to cache the compiled matcher and reuse if using such regex at high frequency (OP does not say what scenario it is used it - might be a rare scenario to clean up data from a form submission or could be used in a tight loop being called 1000s of times a second). – Volksman Nov 19 '19 at 20:32
  • In regard to performance concerns i added a new answer which runs a quick benchmark on a variety of the answers provided. If the OP is doing this operation frequently then they should avoid the String.replace() option as the repeated recompilation of the regex pattern under the hood is very costly. – Volksman Nov 19 '19 at 21:53
  • Is it really the point of whether my solution could be made a tenth faster, even though the downgraded solution **is and was** already n times (in this case 4×) faster than the _"best"_ solution? – Kaplan Nov 21 '19 at 08:27
  • Your first comment above took this from a 'convenient solution' discussion to a run time performance issue. Once you shift focus towards the issue of performance you must realize that signals a "gloves off" scenario in SO world :) In any case, if you want to discuss relative performance, the native Java implementation at 157 ms is 37% faster than your Lambda implementation at 253 ms. – Volksman Nov 24 '19 at 05:05
0

…another lambda
copying a new string from the original, but leaving out the character that is to delete

String text = "removing a special character from a string";

int delete = 'e';
int[] arr = text.codePoints().filter( c -> c != delete ).toArray();

String rslt = new String( arr, 0, arr.length );

gives: rmoving a spcial charactr from a string

Kaplan
  • 2,572
  • 13
  • 14
-1
package com.acn.demo.action;

public class RemoveCharFromString {

    static String input = "";
    public static void main(String[] args) {
        input = "abadbbeb34erterb";
        char token = 'b';
        removeChar(token);
    }

    private static void removeChar(char token) {
        // TODO Auto-generated method stub
        System.out.println(input);
        for (int i=0;i<input.length();i++) {
            if (input.charAt(i) == token) {
            input = input.replace(input.charAt(i), ' ');
                System.out.println("MATCH FOUND");
            }
            input = input.replaceAll(" ", "");
            System.out.println(input);
        }
    }
}
Amos M. Carpenter
  • 4,848
  • 4
  • 42
  • 72
-4

You can use str = str.replace("X", ""); as mentioned before and you will be fine. For your information '' is not an empty (or a valid) character but '\0' is.

So you could use str = str.replace('X', '\0'); instead.

Foivos
  • 1
  • 1
  • 10
    this is incorrect. '\0' will produce an actual null character. str.replace('X', '\0') is equivalent to str.replace("X", "\u0000") which is not at all what the OP wanted – Andrey Jul 26 '12 at 18:00