4

So I have a string like

Refurbished Engine for 2000cc Vehicles

I would like to turn this into

Refurbished Engine for 2000CC Vehicles

With capital cc on the 2000CC. I obviously can't do text.replaceAll("cc","CC"); because it would replace all the occurrences of cc with capital versions so the word accelerator would become aCCelerator. In my scenario the leading four digits will always be four digits followed by the letters cc so I figure this can be done with regex.

My question is how in Java can I turn the cc into CC when it follows 4 digits and obtain the result I am expecting above?

String text = text.replaceAll("[0-9]{4}[c]{2}", "?");
3
  • You can say text.toUpperCase(); Commented Feb 11, 2014 at 17:11
  • 1
    You don't need the brackets surrounding the "c" by the way. ;) Commented Feb 11, 2014 at 17:12
  • @Zeus This will then put all other words in the sentance to uppercase. I need leading caps for which I am using apaches WordUtils.CapitalizeFully method to achieve this. Thanks for suggestion though. Commented Feb 11, 2014 at 17:12

4 Answers 4

7

You can try with

text = text.replaceAll("(\\d{4})cc", "$1CC");
//                          ↓          ↑
//                          +→→→→→→→→→→+

Trick is to place number in group (via parenthesis) and later use match from this group in replacement part (via $x where x is group number).

You can surround that regex with word boundaries "\\b" if you want to make sure that matched text is not part of some other word. You can also use look-adound mechanisms to ensure that there are no alphanumeric characters before and/or after matched text.

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

7 Comments

@Gene \\1 works in regex part $1 in replacement part
Exactly right. Thanks. The mix of Java strings and regexes (compared to Perl, Ruby, etc where they are built-in) gets me again and again...
@Gene No problem. Happens to everyone :)
This also worked for my test cases so far. So many solutions and only one answer I can accept :-).
@AshleySwatton I am glad it works for you :) Feel free to accept answer you like the most since all answers posted here will solve your problem.
|
4

If you just have to convert cc to uppercase, and if it is fixed, then you can just replace the match with CC.

There is no one-liner generic solution for this in Java. You have to do this with Matcher#appendReplacement() and Matcher#appendTail():

String str = "Refurbished Engine for 2000cc Vehicles";
Pattern pattern = Pattern.compile("\\d{4}cc");
Matcher matcher = pattern.matcher(str);

StringBuffer result = new StringBuffer();
while (matcher.find()) {
    matcher.appendReplacement(result, matcher.group().toUpperCase());
}

matcher.appendTail(result);

System.out.println(result.toString());

4 Comments

Thanks. This works a treat and also works for 'Heater Control Pod Nearside (Left) 1700cc–2000cc'.
"There is no one-liner generic solution for this in Java."? The one-liners in the other answers work fine.
@ChristofferHammarström Which generic one-liners do you mean? All I see is special-cased one-liners.
D'oh, you're right. I have no idea what i was thinking.
2

You could perhaps do:

String text = text.replaceAll("(?<=\\b[0-9]{4})cc\\b", "CC");

(?<=\\b[0-9]{4}) is a positive lookbehind that will ensure a match only if cc is preceded by 4 digits (no more than 4 and this rule is enforced by the word boundary \\b (this matches only at the ends of a word, where a word is defined as a group of characters matching \\w+). Also, since lookbehinds are zero-width assertions, they don't count in the match.

If the number of cc's can vary, then it might be easiest checking only one number:

String text = text.replaceAll("(?<=[0-9])cc\\b", "CC");

Comments

2

One way is to trap the numeric part as a group with () and then use a backreference to that group in the substitution:

This is tested:

public static void main(String [] args) {
    String s = "1000cc abc 9999cc";
    String t = s.replaceAll("(\\d{4})cc", "$1CC");
    System.err.println(t);
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.