How to replace case insensitive letter substrings in Java

Using the replace(CharSequence target, CharSequence replacement) method in String, how can I make the target case insensitive?

For example, how it works right now:

 String target = "FooBar"; target.replace("Foo", "") // would return "Bar" String target = "fooBar"; target.replace("Foo", "") // would return "fooBar" 

How can I make it replace (or, if there is a more appropriate method) case insensitive so that both examples return "Bar"?

+82
java string substring replace case-insensitive
Feb 20 '11 at 3:13
source share
6 answers
 String target = "FOOBar"; target = target.replaceAll("(?i)foo", ""); System.out.println(target); 

Output:

 Bar 

It is worth noting that replaceAll treats the first argument as a regular expression pattern, which can cause unexpected results. To solve this problem, use Pattern.quote as indicated in the comments.

+198
Feb 20 '11 at 3:23
source share

Not as elegant as the other approaches, but it is quite simple and easy to use, especially. for people newer to Java. One thing that calls me in the String class is this: it has been around for a very long time, and although it supports global regex and global strings replacements (via CharSequences), the latter does not have a simple boolean parameter: 'isCaseInsensitive'. In fact, you thought that just adding that one small switch, all the problems associated with its absence for beginners, especially could be avoided. Now on JDK 7 String still does not support this one small addition!

OK, I will stop grabbing. For everyone, particularly newer ones for Java, here is your cut and paste deus ex machina. As I said, it’s not so elegant and will not win any weak prizes for coding, but it works and is reliable. Any comments feel free to contribute. (Yes, I know, StringBuffer is probably the best choice for controlling two mutation lines of a string of characters, but it's fairly easy to exchange techniques.)

 public String replaceAll(String findtxt, String replacetxt, String str, boolean isCaseInsensitive) { if (str == null) { return null; } if (findtxt == null || findtxt.length() == 0) { return str; } if (findtxt.length() > str.length()) { return str; } int counter = 0; String thesubstr = ""; while ((counter < str.length()) && (str.substring(counter).length() >= findtxt.length())) { thesubstr = str.substring(counter, counter + findtxt.length()); if (isCaseInsensitive) { if (thesubstr.equalsIgnoreCase(findtxt)) { str = str.substring(0, counter) + replacetxt + str.substring(counter + findtxt.length()); // Failing to increment counter by replacetxt.length() leaves you open // to an infinite-replacement loop scenario: Go to replace "a" with "aa" but // increment counter by only 1 and you'll be replacing 'a forever. counter += replacetxt.length(); } else { counter++; // No match so move on to the next character from // which to check for a findtxt string match. } } else { if (thesubstr.equals(findtxt)) { str = str.substring(0, counter) + replacetxt + str.substring(counter + findtxt.length()); counter += replacetxt.length(); } else { counter++; } } } return str; } 
+10
May 15 '13 at 20:23
source share

If you care, then it may not matter to you whether it will return the whole value:

 target.toUpperCase().replace("FOO", ""); 
+6
Feb 20 '11 at 3:19
source share

Regular expressions are quite difficult to control because some characters are reserved: for example, "foo.bar".replaceAll(".") Creates an empty string because the dot means "whatever." If you want to replace only the point, you should specify "\\." As the parameter .

A simpler solution is to use StringBuilder objects to find and replace text. Two are required: one containing the text in lower case, and the second - the original. The search is performed in lower case, and the detected index will also replace the source text.

 public class LowerCaseReplace { public static String replace(String source, String target, String replacement) { StringBuilder sbSource = new StringBuilder(source); StringBuilder sbSourceLower = new StringBuilder(source.toLowerCase()); String searchString = target.toLowerCase(); int idx = 0; while((idx = sbSourceLower.indexOf(searchString, idx)) != -1) { sbSource.replace(idx, idx + searchString.length(), replacement); sbSourceLower.replace(idx, idx + searchString.length(), replacement); idx+= replacement.length(); } sbSourceLower.setLength(0); sbSourceLower.trimToSize(); sbSourceLower = null; return sbSource.toString(); } public static void main(String[] args) { System.out.println(replace("xXXxyyyXxxuuuuoooo", "xx", "**")); System.out.println(replace("FOoBaR", "bar", "*")); } } 
+6
Aug 19 '12 at 13:18
source share

I like smas answer which uses replaceAll with regex. If you intend to do the same replacement many times, it makes sense to precompile the regular expression once:

 import java.util.regex.Pattern; public class Test { private static final Pattern fooPattern = Pattern.compile("(?i)foo"); private static removeFoo(s){ if (s != null) s = fooPattern.matcher(s).replaceAll(""); return s; } public static void main(String[] args) { System.out.println(removeFoo("FOOBar")); } } 
+4
Apr 15 '15 at 2:59
source share

For non-Unicode characters:

 String result = Pattern.compile("(?i)", Pattern.UNICODE_CASE).matcher(source).replaceAll(""); 
+4
Mar 03 '17 at 16:23
source share



All Articles