I'd like to replace all instances of a substring in a string but String.replaceAll() only accepts a pattern. The string that I have came from a previous match. Is it possible to add escapes to the pattern that I have or is there a version of replaceAll() in another class which accepts a literal string instead of a pattern?
Just use String.replace(CharSequence,CharSequence) rather than replaceAll.
NB: replace doesn't just replace the first occurrence, it replaces all occurrences, like replaceAll.
The method to add escapes is Pattern.quote().
String replaced = myString.replaceAll(Pattern.quote(matchingStr), replacementStr)
But as Jon says you can just use replace(). Despite the fact that it deviates from the replaceAll name, it does replace all occurrences just like replaceAll().
Related
I have a string
s1 = "7+8";
and
s2 = "7+";
I am using the following code to subtract s2 from s1
System.out.println(s1.replaceAll(s2,""));
but it is giving output as
"+8"
Why is this happening??
The regular expression "7+" matches one or more instances of "7". This is what is replaced, leaving "+8".
If you want to match exact strings, rather than regular expressions, use replace instead of replaceAll.
s1.replace(s2, "")
What happens is that the method replaceAll() uses a regex (regular expression) to determine what to replace.
String java.lang.String.replaceAll(String regex, String replacement):
Replaces each substring of this string that matches the given regular expression with the given replacement.
What can you do? You may want to use the method replace() that uses strings literally to replace:
System.out.println(s1.replace(s2, ""));
As an answer to your question (Why is this happening??), String.replaceAll takes a RegEx as first parameter.
You may want to use String.replace
System.out.println(s1.replace(s2, ""));
I have a url like
/.../Male/...
or
/../Female/...
Now i want to do something like follows to replace the string's male female part with foo
/../foo/..
What is the regular expression for this...
currently i am doing like below but no success
url.replace("(fe)?male","foo")
You need to use replaceAll to use a regex, and the expression could be even simpler:
url.replaceAll("(Fem|M)ale","foo");
or
url.replaceAll("Female|Male","foo");
You need replaceAll(), which uses regex for find what to replace, not replace(), which finds plain text:
url = url.replaceAll("(fe)?male","foo");
Also note that String are immutable, so calling a replace method doesn't change the String, it returns a new String with the changes made, so you must assign the result back to the variable.
A better regex would be:
url = url.replaceAll("(?i)\\b(fe)?male\\b","foo");
The \b regex makes sure what's being replaced is the whole word female/male. Without \b it would replace "male" in "malediction".
The (?i) makes the match case insensitive.
You need to use replaceAll for patterns.
Also you should consider using a case-insensitive pattern, as such:
String input = ".../Female/...";
System.out.println(input.replaceAll("(?i)(fe)?male", "foo"));
Output:
.../foo/...
For a string str_in = "instance (\\w+\\s+){0,8}deleted"; how can I extract instance and deleted by using the replaceAll function?
I tried str_in = str_in.replaceAll("(\\w+\\s+){0,8}", ""); but it didn't work.
If you, as your question states, really want to use replaceAll() instead of the (in my opinion more suitable) replace(), you can use the \Q and \E markers to match the string literally:
String str_in = "instance (\\w+\\s+){0,8}deleted";
System.out.println(str_in.replaceAll("\\Q(\\w+\\s+){0,8}\\E", ""));
prints
instance deleted
You will need to escape the single characters so that they lose their regex nature:
str_in.replaceAll("\\(\\\\w\\+\\\\s\\+\\)\\{0,8\\}", "")
Each escaping backslash needs to be escaped for itself because of the string literal.
Do you mean that (\\w+\\s+){0,8} is literally in the string, and you want to remove it? You will need to escape each \ again in your replaceAll, so that they are interpreted literally, not as part of a regex, and also the ( and {.
Use str_in.replace("(\\w+\\s+){0,8}", "");
replace()
Replaces each substring of this string that matches the literal target
sequence with the specified literal replacement sequence. The
replacement proceeds from the beginning of the string to the end, for
example, replacing "aa" with "b" in the string "aaa" will result in
"ba" rather than "ab"
replaceAll()
Replaces each substring of this string that matches the given regular expression with the given replacement
here monitorUrl contains- http://host:8810/solr/admin/stats.jsp
and monitorUrl sometimes can be-- http://host:8810/solr/admin/monitor.jsp
So i want to replace stats.jsp and monitor.jsp to ping
if(monitorUrl.contains("stats.jsp") || monitorUrl.contains("monitor.jsp")) {
trimUrl = monitorUrl.replace("[stats|monitor].jsp", "ping");
}
Anything wrong with the above code. As I get the same value of monitorUrl in trimUrl.
Try using replaceAll instead of replace (and escape the dot as Alan pointed out):
trimUrl = monitorUrl.replaceAll("(stats|monitor)\\.jsp", "ping");
From the documentation:
replaceAll
public String replaceAll(String regex, String replacement)
Replaces each substring of this string that matches the given regular expression with the given replacement.
Note: You may also want to consider matching only after a / and checking that it is at the end of the line by using $ at the end of your regular expression.
I think this is what you're looking for:
trimUrl = monitorUrl.replaceAll("(?:stats|monitor)\\.jsp", "ping");
Explanation:
replaceAll() treats the first argument as a regex, while replace() treats it as a literal string.
You use parentheses, not square brackets, to group things. (?:...) is the non-capturing form of group; you should use the capturing form - (...) - only when you really need to capture something.
. is a metacharacter, so you need to escape it if you want to match a literal dot.
And finally, you don't have to check for the presence of the sentinel string separately; if it's not there, replaceAll() just returns the original string. For that matter, so does replace(); you could also have done this:
trimUrl = monitorUrl.replace("stats.jsp", "ping")
.replace("monitor.jsp", "ping");
No needs to use regex (also replace() don't use regex).
trimUrl = monitorUrl.replace("stats.jsp", "ping").replace("monitor.jsp", "ping");
In Java, suppose I have a String variable S, and I want to search for it inside of another String T, like so:
if (T.matches(S)) ...
(note: the above line was T.contains() until a few posts pointed out that that method does not use regexes. My bad.)
But now suppose S may have unsavory characters in it. For instance, let S = "[hi". The left square bracket is going to cause the regex to fail. Is there a function I can call to escape S so that this doesn't happen? In this particular case, I would like it to be transformed to "\[hi".
String.contains does not use regex, so there isn't a problem in this case.
Where a regex is required, rather rejecting strings with regex special characters, use java.util.regex.Pattern.quote to escape them.
As Tom Hawtin said, you need to quote the pattern. You can do this in two ways (edit: actually three ways, as pointed out by #diastrophism):
Surround the string with "\Q" and "\E", like:
if (T.matches("\\Q" + S + "\\E"))
Use Pattern instead. The code would be something like this:
Pattern sPattern = Pattern.compile(S, Pattern.LITERAL);
if (sPattern.matcher(T).matches()) { /* do something */ }
This way, you can cache the compiled Pattern and reuse it. If you are using the same regex more than once, you almost certainly want to do it this way.
Note that if you are using regular expressions to test whether a string is inside a larger string, you should put .* at the start and end of the expression. But this will not work if you are quoting the pattern, since it will then be looking for actual dots. So, are you absolutely certain you want to be using regular expressions?
Try Pattern.quote(String). It will fix up anything that has special meaning in the string.
Any particular reason not to use String.indexOf() instead? That way it will always be interpreted as a regular string rather than a regex.
Regex uses the backslash character '\' to escape a literal. Given that java also uses the backslash character you would need to use a double bashslash like:
String S = "\\[hi"
That will become the String:
\[hi
which will be passed to the regex.
Or if you only care about a literal String and don't need a regex you could do the following:
if (T.indexOf("[hi") != -1) {
T.contains() (according to javadoc : http://java.sun.com/javase/6/docs/api/java/lang/String.html) does not use regexes. contains() delegates to indexOf() only.
So, there are NO regexes used here. Were you thinking of some other String method ?