简体   繁体   中英

Pattern.matcher(s).replaceAll(“$1$2$3”) Transform only $2 to lowercase

I have a String like this

final String text = "Some Text #AAAA some Other text .." (# with 4 uppercase letters)

Pattern patt = Patter.compile("(.*?)(#)([A-Z]{4})(.*?)");
patt.matcher(text ).replaceAll("$1$3$4")

remove only the # in text

I would have AAAA in lowercase, result expected :

Some Text aaaa some Other text ..

How have this result in lower case, only for the four AAAA ?

Rather than use replaceAll directly you'll have to do the appendReplacement loop yourself. I would use a simpler regex:

Pattern patt = Patter.compile("#([A-Z]{4})");
Matcher mat = patt.matcher(text);
StringBuffer buf = new StringBuffer();
while(mat.find()) {
  mat.appendReplacement(buf, mat.group(1).toLowerCase());
}
mat.appendTail(buf);

Normally you have to watch out with appendReplacement (and replaceAll ) and use Matcher.quoteReplacement if the replacement string might contain $ signs or backslashes, but in this case we know that can't happen as group 1 will always be exactly four letters.

This will work:

Matcher matcher = patt.matcher(text);
matcher.matches();
String res = matcher.group(1) + matcher.group(3).toLowerCase() + matcher.group(4);

here is an oneliner:

String text2 = text.replaceFirst("(?<=#)[A-Z]{4}", text.replaceAll(".*?#([A-Z]{4}).*", "$1").toLowerCase());

take your example:

final String text = "Some Text #AAAA some Other text ..";
        String text2 = text.replaceFirst("(?<=#)[A-Z]{4}", text.replaceAll(".*?#([A-Z]{4}).*", "$1").toLowerCase());
        System.out.println(text2);

will output:

Some Text #aaaa some Other text ..

Try this :

public static void main (String args[]) {
    String matched = "";
    Pattern pattern = Pattern.compile("(.*?)(#)([A-Z]{4})(.*?)");
    Matcher matcher = pattern.matcher("Some Text #AAAA some Other text");
    if (matcher.find()) {   
        matched =  matcher.group(1) + matcher.group(3).toLowerCase() + matcher.group(4);
    }
    System.out.println(matched);
}

Quote from the Matcher.replaceAll() API page :

Note that backslashes ( \\ ) and dollar signs ( $ ) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Dollar signs may be treated as references to captured subsequences.

This sounds exactly like the problem you're facing...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM