4

I have a string that looks like this:

CALDARI_STARSHIP_ENGINEERING

and I need to edit it to look like

Caldari Starship Engineering

Unfortunately it's three in the morning and I cannot for the life of me figure this out. I've always had trouble with replacing stuff in strings so any help would be awesome and would help me understand how to do this in the future.

3
  • 2
    in a few minutes polygenelubricants will come along and write some wicked cleaver regexp that I don't understand... Commented May 16, 2010 at 7:58
  • 1
    @aioobe: I'm always more than happy to explain regex whenever my answer is unclear, although of course it helps if people also know the basics. Commented May 17, 2010 at 6:33
  • Sure. You always provide sufficient links etc for me to understand. What I meant was more like, "soon polygenelubricants will surprise me again with what regexps are capable of" :-) I just wrote a reg-exp variant of your solution for fun. I believe it's robust against the isEmpty check that you have (but it's probably not as efficient as your solution). Commented May 17, 2010 at 7:48

5 Answers 5

9

Something like this is simple enough:

    String text = "CALDARI_STARSHIP_ENGINEERING";
    text = text.replace("_", " ");
    StringBuilder out = new StringBuilder();
    for (String s : text.split("\\b")) {
        if (!s.isEmpty()) {
            out.append(s.substring(0, 1) + s.substring(1).toLowerCase());
        }
    }
    System.out.println("[" + out.toString() + "]");
    // prints "[Caldari Starship Engineering]"

This split on the word boundary anchor.

See also


Matcher loop solution

If you don't mind using StringBuffer, you can also use Matcher.appendReplacement/Tail loop like this:

    String text = "CALDARI_STARSHIP_ENGINEERING";
    text = text.replace("_", " ");

    Matcher m = Pattern.compile("(?<=\\b\\w)\\w+").matcher(text);
    StringBuffer sb = new StringBuffer();
    while (m.find()) {
        m.appendReplacement(sb, m.group().toLowerCase());
    }
    m.appendTail(sb);
    System.out.println("[" + sb.toString() + "]");
    // prints "[Caldari Starship Engineering]"

The regex uses assertion to match the "tail" part of a word, the portion that needs to be lowercased. It looks behind (?<=...) to see that there's a word boundary \b followed by a word character \w. Any remaining \w+ would then need to be matched so it can be lowercased.

Related questions

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

3 Comments

+1 Easy, understandable solution without using 3rd party stuff.
I suggest using StringBuilder because it is faster. The StringBuffer should replace StringBuilder only when you suppose concurrency issues in a multi-threaded application.
@Leni: unfortunately Matcher.appendReplacement/Tail only accepts StringBuffer. If you want to use StringBuilder, then you can't use those methods.
4

You can try this:

String originalString = "CALDARI_STARSHIP_ENGINEERING";
String newString =
    WordUtils.capitalize(originalString.replace('_', ' ').toLowerCase());

WordUtils are part of the Commons Lang libraries (http://commons.apache.org/lang/)

4 Comments

@In silico - you are assuming WordUtils are available and can be used.
So where does WordUtils come from?
Apache Commons Lang. org.apache.commons.lang
Edited it to mention that it comes from the Commons Lang libraries.
1

Using reg-exps:

String s = "CALDARI_STARSHIP_ENGINEERING";
StringBuilder camel = new StringBuilder();
Matcher m = Pattern.compile("([^_])([^_]*)").matcher(s);
while (m.find())
    camel.append(m.group(1)).append(m.group(2).toLowerCase());

Comments

0

Untested, but thats how I implemented the same some time ago:

s = "CALDARI_STARSHIP_ENGINEERING";
StringBuilder b = new StringBuilder();
boolean upper = true;
for(char c : s.toCharArray()) {
    if( upper ) {
        b.append(c);
        upper = false;
    } else if( c = '_' ) {
        b.append(" ");
        upper = true;
    } else {
        b.append(Character.toLowerCase(c));
    }
}
s = b.toString();

Please note that the EVE license agreements might forbit writing external tools that help you in your careers. And it might be the trigger for you to learn Python, because most of EVE is written in Python :).

4 Comments

Yep - if you change else if( c = '_' ) this is fine
Daniel, there's EveMon, gtkEveMon, EFT, and the fact that CCP provides both a database dump and an API for this.
Oh. I assume you can't play Eve anymore without your own Trade monitoring system, Guild tracking system and the like? :)
Nah, there's ISK to be made. Just nice to be able to instantly check what can make the highest profits... and a neat programming project to boot!
0

Quick and dirty way:

Lower case all

   line.toLowerCase();

Split into words:

   String[] words = line.split("_");

Then loop through words capitalising first letter:

  words[i].substring(0, 1).toUpperCase() 

1 Comment

Need to lower case all first and then capitalise first letter

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.