7

Let's consider the following example:

String s = str.replaceAll("regexp", "$1");

Some languages allow us to specify \U$1 in place of $1 which converts matched groups with uppercase letters. How can I achieve the same using Java?

I know we can use Pattern class and get the group and convert it to uppercase, but that's not what I am looking for. I want to just change $1 with something that gets the job done.

I have also tried:

String s = str.replaceAll("regexp", "$1".toUpperCase());

But it looks like "$1".toUpperCase() is "$1" and not the match. I confirmed it using:

String s = str.replaceAll("regexp", method("$1"));

// method declared as method()
private static String method(String s) {
    System.out.println(s); // prints "$1"
    return s;
}

Is it even allowed in Java?

EDIT:

String s = "abc";
System.out.println(s.replaceAll("(a)", "$1")); // should print "Abc"

EDIT FOR POSSIBLE DUPE:

I am not looking for way using m.group(), is it possible using something like \U$1 in place of $1 with replaceAll()

13
  • pls provide starting and ending result. Commented Feb 3, 2018 at 11:34
  • @Black.Jack I have updated the question Commented Feb 3, 2018 at 11:38
  • can't get the difference with toUppercase() Commented Feb 3, 2018 at 11:40
  • 1
    To @Maroun, I know this won't be tagged to you but if you have read my question properly, you won't have marked this as a dupe. Commented Feb 3, 2018 at 12:01
  • 1
    The question is fairly simple, I am looking for concise version of doing it. Commented Feb 3, 2018 at 12:06

3 Answers 3

2

\\U is not implemented in the java regex AFAIK and you can't do it with a regex as such (.NET has it IIRC). It's a bit verbose, but one way to do it would be:

    String test = "abc";
    Pattern p = Pattern.compile("(a)");
    Matcher m = p.matcher(test);

    StringBuilder sb = new StringBuilder();
    if (m.find()) {
        String match = test.substring(m.start(1), m.end(1));
        m.appendReplacement(sb, match.toUpperCase());
    }

    m.appendTail(sb);
    System.out.println(sb.toString()); 
Sign up to request clarification or add additional context in comments.

Comments

1

Since Java 9, we can provide a Function to Matcher#replaceAll(Function<MatchResult,​String> replacer). It is more concise than other answers here. Eg:

Pattern.compile("regexp")
       .matcher(str)
       .replaceAll(mr -> mr.group().toUpperCase());

We can fully customize this behaviour since we have a hold on MatchResult:

Pattern.compile("regexp")
       .matcher(str)
       .replaceAll(mr -> {
                String.format("%s %s", 
                              mr.group(1).toUpperCase),
                              mr.group(2).indent(4);
                   });

Comments

0

I think you should consider StringUtils from Apache Commons.

This is an example:

String s = "abcad";

String replacer = "a";

System.out.println(StringUtils.replaceChars(s, replacer, replacer.toUpperCase()));//<--AbcAd

Pls also consider this avoids you to implement the algorythm that necessarily will be under the hood, and the fact the every jar library introduced in a project is basically a new weak point.

This is maven dependency:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.7</version>
</dependency>

Hope it helps.

5 Comments

Sure but the Op explicity doesn't want to use that approach.
If you did not notice, I posted the OP.
yes, if u prefer you coul put your strings inside replace chars. that would be one line. So ? less than one line?
I don't understand, show me the code. What I think you mean to create at least two String objects in that case right?
@roundAbout strings are immutable anyway, so you would create more instances anyway

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.