Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace group 1 of Java regex with out replacing the entire regex

Tags:

java

regex

I have a regex pattern that will have only one group. I need to find texts in the input strings that follows the pattern and replace ONLY the match group 1. For example I have the regex pattern and the string to be applied on as shown below. The replacement string is "<---->"

Pattern p = Pattern.compile("\\w*(lan)\\w+");
Matcher m = p.matcher("plan plans lander planitia");

The expected result is

plan p<--->s <--->der p<--->itia

I tried following approaches

    String test = "plan plans lander planitia";
    Pattern p = Pattern.compile("\\w*(lan)\\w+");
    Matcher m = p.matcher(test);
    String result = "";
    while(m.find()){
        result = test.replaceAll(m.group(1),"<--->");
    }
    System.out.print(result);

This gives result as

p<---> p<--->s <--->der p<--->itia

Another approach

    String test = "plan plans lander planitia";
    Pattern p = Pattern.compile("\\w*(lan)\\w+");
    Matcher m = p.matcher(test);
    String result = "";
    while(m.find()){
        result = test.replaceAll("\\w*(lan)\\w+","<--->");
    }
    System.out.print(result);

Result is

plan <---> <---> <--->

I have gone through this link. Here the part of the string before the match is always constant and is "foo" but in my case it varies. Also I have looked at this and this but I am unable to apply any on the solutions given to my present scenario.

Any help is appreciated

like image 640
Aditya Avatar asked Jul 10 '16 21:07

Aditya


People also ask

How do you find and replace in a regular expression in Java?

They can be used to search, edit, or manipulate text and data. The replaceFirst() and replaceAll() methods replace the text that matches a given regular expression. As their names indicate, replaceFirst replaces the first occurrence, and replaceAll replaces all occurrences.

What is $1 regex Java?

$0 = the entire matched substring (corresponding to matcher. group()), $1 = the first parenthesized match subpattern (corresponding to matcher.

How do you replace a character in a string in Java regex?

To replace one string with another string using Java Regular Expressions, we need to use the replaceAll() method. The replaceAll() method returns a String replacing all the character sequence matching the regular expression and String after replacement.


1 Answers

You need to use the following pattern with capturing groups:

(\w*)lan(\w+)
^-1-^   ^-2-^

and replace with $1<--->$2

See the regex demo

The point is that we use a capturing group around the parts that we want to keep and just match what we want to discard.

Java demo:

String str = "plan plans lander planitia";
System.out.println(str.replaceAll("(\\w*)lan(\\w+)", "$1<--->$2"));
// => plan p<--->s <--->der p<--->itia

If you need to be able to replace the Group 1 and keep the rest, you may use the replace callback method emulation with Matcher#appendReplacement:

String text = "plan plans lander planitia";
String pattern = "\\w*(lan)\\w+";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(text);
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, m.group(0).replaceFirst(Pattern.quote(m.group(1)), "<--->"));
}
m.appendTail(sb); // append the rest of the contents
System.out.println(sb.toString());
// output => plan p<--->s <--->der p<--->itia

See another Java demo

Here, since we process a match by match, we should only replace the Group 1 contents once with replaceFirst, and since we replace the substring as a literal, we should Pattern.quote it.

like image 166
Wiktor Stribiżew Avatar answered Oct 17 '22 06:10

Wiktor Stribiżew