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/...
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 string field. I need to pass UUID string or digits number to that field.
So I want to validate this passing value using regex.
sample :
stringField = "1af6e22e-1d7e-4dab-a31c-38e0b88de807";
stringField = "123654";
For UUID I can use,
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
For digits I can use
"\\d+"
Is there any way to use above 2 pattern in single regex
Yes..you can use |(OR) between those two regex..
[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}|\\d+
^
try:
"(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})|(?:\\d+)"
You can group regular expressions with () and use | to allow alternatives.
So this will work:
(([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12})|(\\d+)
Note that I've adjusted your UUID regular expression a little to allow for upper case letters.
How are you applying the regex? If you use the matches(), all you have to do is OR them together as #Anirudh said:
return myString.matches(
"[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}|\\d+");
This works because matches() acts as if the regex were enclosed in a non-capturing group and anchored at both ends, like so:
"^(?:[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}|\\d+)$"
If you use Matcher's find() method, you have to add the group and the anchors yourself. That's because find() returns a positive result if any substring of the string matches the regex. For example, "xyz123<>&&" would match because the "123" matches the "\\d+" in your regex.
But I recommend you add the explicit group and anchors anyway, no matter what method you use. In fact, you probably want to add the inline modifier for case-insensitivity:
"(?i)^(?:[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}|\\d+)$"
This way, anyone who looks at the regex will be able to tell exactly what it's meant to do. They won't have to notice that you're using the matches() method and remember that matches() automatically anchors the match. (This will be especially helpful for people who learned regexes in a non-Java context. Almost every other regex flavor in the world uses the find() semantics by default, and has no equivalent for Java's matches(); that's what anchors are for.)
In case you're wondering, the group is necessary because alternation (the | operator) has the lowest precedence of all the regex constructs. This regex would match a string that starts with something that looks like a UUID or ends with one or more digits.
"^[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}|\\d+$" // WRONG
I'm trying to achieve this - If a string contains the pattern %25 followed by any number of alpha-numeric characters, then i need to replace %25 with %. The following code doesn't seem to be right-
while (userPassword.contains("%25"+"[^A-Za-z0-9]*")) {
userPassword = userPassword.replace("%25", "%");
}
The method String.contains() does not work with regular expressions, but with simple texts, so you are actually looking at the exact sequence "%25[^A-Za-z0-9]" in your string. Also, ^ means that it should match what is NOT in the character class, that is no alphanumeric character, and this is the opposite of what you want.
You can instead use the method String.matches:
while (userPassword.matches(".*%25[A-Za-z0-9]*"))
(As you see, I put all the regular expression in a single string. The compiler would have done that for you, but it's more clear)
For example:
String userPassword = "%25sdflk42";
System.out.println(userPassword.contains("%25"+"[A-Za-z0-9]*"));
System.out.println(userPassword.matches(".*%25[A-Za-z0-9]*"));
This will print:
false
true
You need to be careful here. String.contains does not interpret the argument as regex.
Try this:
userPassword = userPassword.replaceAll("%25([a-zA-Z0-9]*)", "%$1");
Which uses back-referencing to replace only a part of the captured pattern. From the documentation:
Dollar signs may be treated as references to captured subsequences.
while (userPassword.contains("%25"+"[^A-Za-z0-9]*"))
should be
while (userPassword.contains("%25"+"[A-Za-z0-9]*"))
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 ?