M. Nowin M. Nowin - 8 days ago 6
Java Question

Java Regex compress String

I have random String for example

"aaaaaaBccccCCCCd"
I need make regex wich schare the text for groups to get effect
"a6B1c4C4d1"
. My regex looks like that
"(\\D+)\\D*\\1"
but he lost single letters, so in this sample
B
and
d
.

Maybe someone would have an idea?

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Compress {
public static void main(String[] args) {
String text = "aaaaaaBccccCCCCd";
String regex = "(\\D+)\\D*\\1"; // or (.+).*\\1
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
String result = new String();
while (matcher.find()) {
String letter = matcher.group().substring(0, 1);
String numberOfLetter = String.valueOf(matcher.group().length());
result = result + letter + numberOfLetter;
}
System.out.println(result);
}
}


Thank you.

Answer

Use the following approach based on Matcher#appendReplacement:

String text = "aaaaaaBccccCCCCd"; //a6B1c4C4d1
String regex = "(.)(\\1*)"; 
String pattern = "test";
Pattern r = Pattern.compile(regex);
Matcher m = r.matcher(text);
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, m.group(1) + (m.group(2).length()+1));
}
m.appendTail(sb);
System.out.println(sb);

See the Java demo

The (.)(\1*) will capture any char into Group 1 and then will capture into Group 2 zero or more repetitions of the same content. In the "callback", Group 1 is concatenated with the length of Group 2 incremented to account for the Group 1 length.

Comments