Recognizing and replacing parts of a string in java 7 - java

I want to replace a part of a string with another string. For example, a string comes in, and it contains meat, but I want it to change that meat to vegetable. I know I can do this with the following statement.
str = str.replaceAll("meat", "vegetable");
However, I need to have the exact capitalization. I'm looking for a way to do this no matter what letters are upper or lowercase in the example meat.
My application is a filter for Minecraft. Either swears, or just customizing the menu. Like I'd like to replace every instance of the word minecraft, no matter the capitalization, to say Best game Ever!!.
I have modded it so that it can recognize and replace specific capitalizations, but that is very limiting.
I hope I have supplied enough info so that someone can help me with this.

You can make regex case-insensitive by adding (?i) flag at start
str = str.replaceAll("(?i)meat", "vegatable");
example
System.out.println("aBc def".replaceAll("(?i)abc","X")); // out: "X def"

The first argument to replaceAll is a regular expression, and you can embed a flag in the expression to make it case-insensitive:
str = str.replaceAll("(?i)meat", "vegatable");

Another way: Here the flag is not explicitly in the regex, but passed as a separate parameter.
String input = "abc MeAt def";
Pattern pattern = Pattern.compile("meat", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(input);
String output = matcher.replaceAll("vegetable");
System.out.println(output);

Related

Java Regex to Validate Full Name allow only Spaces ,Letters,commas, dots in java

I'm trying to validate the given string. It should allow (a-z, white space between words,commas,dots only).
I tried this but it doesn't work:
final String name = "/^[a-z]+(\s+[a-z]+)*$/i";
Pattern pattern = Pattern.compile(name );
Matcher matcher = pattern.matcher("Ravi is a java developer");
System.out.println("***********"+matcher.matches());
please suggest to me.
Thanks in advance.
The regex and example you provided will not work, as you don't allow capital letters.
You can try this:
([a-zA-Z]*(\s)*[\.\,]*)*
You need to enable case insensitive modifier (?i)
String s = "Ravi is a java developer";
System.out.println(s.matches("(?i)[a-z]+(\\s+[a-z]+)*")); // true
OR
System.out.println(s.matches("(?i)[a-z]+([,.\\s]+[a-z]+)*")); // true
This Should work:
String name = "[a-zA-z]*([,.\\s]+[a-z]*)*"
And this should be helpful: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
Why complicate?
"^A-Z[a-z \\.,]+$" <-- something that starts with a capital letter and has only letters, space, dots and commas after that.
I'm surprised how complicated regexes the average person creates.

Getting a specific word in a string

I am new to java, i have a string
"rdl_mod_id:0123456789\n\nrdl_mod_name:Driving Test\n\nrdl_mod_type:PUBL\n\nrdl_mod_mode:Practice\n\nrdl_mod_date:2013-04-23"
What I want is to get the Driving Test word. The word is dynamically changes so what I want to happen is get the word between the rdl_mod_name: and the \n.
Try the following.. It will work in your case..
String str = "rdl_mod_id:0123456789\n\nrdl_mod_name:Driving Test\n\nrdl_mod_type:PUBL\n\nrdl_mod_mode:Practice\n\nrdl_mod_date:2013-04-23";
Pattern pattern = Pattern.compile("rdl_mod_name:(.*?)\n");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
Also you can make use of regex,matcher,pattern to get your desired result..
The following links will also give you a fair idea:
Extract string between two strings in java
Java- Extract part of a string between two special characters
How to get a string between two characters?
I would look into java regular expressions (regex). The String matches method uses a regex to determine if there's a pattern in a string. For what you are doing, I would probably use 'matches(rdl_mod_.*\n)'. The '.*' is a wildcard for strings, so in this context it means anything between rdl_mod and \n. I'm not sure if the matches method can process forward slashes (they signify special text characters), so you might have to replace them with either a different character or remove them altogether.
Use java's substring() function with java indexof() function.
Try this code :
String s = "rdl_mod_id:0123456789\n\nrdl_mod_name:Driving Test\n\nrdl_mod_type:PUBL\n\nrdl_mod_mode:Practice\n\nrdl_mod_date:2013-04-23";
String sArr[] = s.split("\n\n");
String[] sArr1 = sArr[1].split(":");
System.out.println("sArr1[1] : " + sArr1[1]);
The s.split("\n\n");will split the string on basis of \n\n.
The second split i.e. sArr[1].split(":"); will split the second element in array sArr on basis of : i.e split rdl_mod_name:Driving Test into rdl_mod_name and Driving Test.
sArr1[1] is your desired result.

what is the regular expression for male and female string

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/...

Using backreference to refer to a pattern rather than actual match

I am trying to write a regex which would match a (not necessarily repeating) sequence of text blocks, e.g.:
foo,bar,foo,bar
My initial thought was to use backreferences, something like
(foo|bar)(,\1)*
But it turns out that this regex only matches foo,foo or bar,bar but not foo,bar or bar,foo (and so on).
Is there any other way to refer to a part of a pattern?
In the real world, foo and bar are 50+ character long regexes and I simply want to avoid copy pasting them to define a sequence.
With a decent regex flavor you could use (foo|bar)(?:,(?-1))* or the like.
But Java does not support subpattern calls.
So you end up having a choice of doing String replace/format like in ajx's answer, or you could condition the comma if you know when it should be present and when not. For example:
(?:(?:foo|bar)(?:,(?!$|\s)|))+
Perhaps you could build your regex bit by bit in Java, as in:
String subRegex = "foo|bar";
String fullRegex = String.format("(%1$s)(,(%1$s))*", subRegex);
The second line could be factored out into a function. The function would take a subexpression and return a full regex that would match a comma-separated list of subexpressions.
The point of the back reference is to match the actual text that matches, not the pattern, so I'm not sure you could use that.
Can you use quantifiers like:
String s= "foo,bar,foo,bar";
String externalPattern = "(foo|bar)"; // comes from somewhere else
Pattern p = Pattern.compile(externalPattern+","+externalPattern+"*");
Matcher m = p.matcher(s);
boolean b = m.find();
which would match 2 or more instances of foo or bar (followed by commas)

How to make regex matching fail if checked string still has leftover characters?

I'm trying to check a string with a regular expression, and this check should only pass if the string contains only *h, *d, *w and/or *m where * can be any number.
So far I've got this:
Pattern p = Pattern.compile("([0-9]h)|([0-9]d)|([0-9]w)|([0-9]m)");
Matcher m = p.matcher(strToCheck);
if(m.find()){
//matching succesful code
}
And it works to detect if there are any of the number-letter combinations present in the checked string, but it also works if the input is, for instance, "12x5d", because it has "5d" in it. I don't know if this is a code problem or a regex problem. Is there a way to achieve what I want?
EDIT:
Thank you for your answers so far, but as requested, I'll try to clarify a bit. A string like "1w 2d 3h" or "1w 1w" is valid and should pass, but something like "1w X 2d 3h", "1wX 2d" or "w d h" should fail.
use m.matches() or add ^ and $ to the beginning and end of the regex resp.
edit but if you wan sequences of these delimited by whitespace (as mentioned in the comments) you can use
Pattern.compile("\\b\\d[hdwm]\\b");
Matcher m = p.matcher(strToCheck);
while(m.find()){
//matching succesful code
}
Firstly, I think you should use matches() instead of find(). The former matches the entire string against the regex, whereas the latter searches within the string.
Secondly, you can simplify the regex like so: "[0-9][hdwm]".
Finally, if the number can contain multiple digits, use the + operator: "[0-9]+[hdwm]"
try this:
Pattern p = Pattern.compile("[0-9][hdwm]");
Matcher m = p.matcher(strToCheck);
if(m.matches()){
//matching succesful code
}
If you want to only accept things like 5d as a complete word, rather than just part of one, you can use the \b "word border" markers in regex:
Pattern p = Pattern.compile("\\b([0-9]h)|([0-9]d)|([0-9]w)|([0-9]m)\\b");
This will let you match a string like "Dimension: 5h" while rejecting a string like "Dimension: 12wx5h".
(If, on the other hand, you only want to match if the entire string is just 5d or the like, then use matches() as others have suggested.)
You can write it like this "^\\d+[hdwm]$". Which should only match on the desired strings.

Categories

Resources