2

I'm trying to replace a url string to lowercase but wanted to keep the certain pattern string as it is.

eg: for input like:

http://BLABLABLA?qUERY=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}

The expected output would be lowercased url but the multiple macros are original:

http://blablabla?query=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}

I was trying to capture the strings using regex but didn't figure out a proper way to do the replacement. Also it seemed using replaceAll() doesn't do the job. Any hint please?

2
  • Which parts exactly should change and how should they change? Based on your title you want to replace with uppercase version, but your examples do something opposite. Commented Aug 15, 2018 at 16:08
  • sorry for the confusion. My point is to twist the upper/lower case of all strings excluding the certain patterned strings, so I wanted to do something like replaceAll("(.*)?\\$\\{\\w+\\}")) and lowercase the (.*) part Commented Aug 15, 2018 at 16:14

2 Answers 2

2

It looks like you want to change any uppercase character which is not inside ${...} to its lowercase form.

With construct

Matcher matcher = ...

StringBuffer buffer = new StringBuffer();
while (matcher.find()){
    String matchedPart = ...
    ...
    matcher.appendReplacement(buffer, replacement); 
}
matcher.appendTail(buffer);
String result = buffer.toString();

or since Java 9 we can use Matcher#replaceAll​(Function<MatchResult,String> replacer) and rewrite it like

String replaced = matcher.replaceAll(m -> {
    String matchedPart = m.group();
    ...
    return replacement;
});

you can dynamically build replacement based on matchedPart.

So you can let your regex first try to match ${...} and later (when ${..} will not be matched because regex cursor will not be placed before it) let it match [A-Z]. While iterating over matches you can decide based on match result (like its length or if it starts with $) if you want to use use as replacement its lowercase form or original form.

BTW regex engine allows us to place in replacement part $x (where x is group id) or ${name} (where name is named group) so we could reuse those parts of match. But if we want to place ${..} as literal in replacement we need to escape \$. To not do it manually we can use Matcher.quoteReplacement.

Demo:

String yourUrlString = "http://BLABLABLA?qUERY=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}";

Pattern p = Pattern.compile("\\$\\{[^}]+\\}|[A-Z]");
Matcher m = p.matcher(yourUrlString);

StringBuffer sb = new StringBuffer();
while(m.find()){
    String match = m.group();
    if (match.length() == 1){
        m.appendReplacement(sb, match.toLowerCase());
    } else {
        m.appendReplacement(sb, Matcher.quoteReplacement(match));
    }
}
m.appendTail(sb);
String replaced = sb.toString();
System.out.println(replaced);

or in Java 9

String replaced = Pattern.compile("\\$\\{[^}]+\\}|[A-Z]")
        .matcher(yourUrlString)
        .replaceAll(m -> {
            String match = m.group();
            if (match.length() == 1)
                return match.toLowerCase();
            else
                return Matcher.quoteReplacement(match); 
        });
System.out.println(replaced);

Output: http://blablabla?query=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}

Sign up to request clarification or add additional context in comments.

1 Comment

Yes this is exactly what I need! I'm with Java 8 so will use the old school way. Thanks so much!
0

This regex will match all the characters before the first &macro, and put everything between http:// and the first &macro in its own group so you can modify it.

http://(.*?)&macro

Tested here

UPDATE: If you don't want to use groups, this regex will match only the characters between http:// and the first &macro

(?<=http://)(.*?)(?=&macro)

Tested here

2 Comments

but this works for only one group of the "macro" right? what if there're multiple of this macro group? and it's the "${macrovalue}" part it needs to keep as it is.
It doesn't matter how many macros you have. It will stop matching once it reaches the first one.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.