2

Assuming I have a String like "MikeJackson" I am trying to figure out a way to put a space in between so it becomes "Mike Jackson". And then applying the same method to another string say "JohnBull" would give me back "John Bull". This is the code I came up with:

public class Test{

    public Test(){

    }
public void sep(String s){
    s = s + " ";
   char[] charArray = s.toCharArray();
   int l = s.length();
for (int i = 0; i < l; i++){
    char p = ' ';

    if(Character.isUpperCase(s.charAt(0))){
        continue;   
    }
    else if (Character.isUpperCase(s.charAt(i))){
        int k = s.indexOf(s.charAt(i));
        charArray[l] = charArray[--l];
        charArray[k-1] = p;
    }
    //System.out.println(s.charAt(i));
}
}
    public static void main (String args[]){

    Test one = new Test();

    one.sep("MikeJackson");
    }  
}

My idea was to add a space to the String so that "MikeJackson" becomes "Mike Jackson " and then shift the characters on place to the right (check for where I find an uppercase) ignoring the first uppercase. Then put a character ' ' in place of the character 'J' but shift 'J' to the right. That's what I was trying to achieve with my method but it looks I need some guidelines. If anyone could help. Thanks.

emi
  • 2,830
  • 5
  • 31
  • 53

7 Answers7

18

Try this:

"MikeJackson".replaceAll("(?!^)([A-Z])", " $1");

For every upper char I am adding a space before.

Also, it works with multiple uppercase words. I am getting Word1 Word2 Word3 for Word1Word2Word3.

Silviu Burcea
  • 5,103
  • 1
  • 29
  • 43
  • the solution is elegant, :-D – raffian Oct 17 '13 at 13:36
  • you could use (A-Z)(?!^) to prevent it from matching the first letter in the String. Then you wouldn't have to use the .trim() – Nathanial Oct 17 '13 at 14:05
  • @Nathanial Isn't that "A [A-Z] not followed by ^"? which is always the case. ^ can't follow anything. EDIT: Tested on http://regexpal.com It doesn't work – Cruncher Oct 17 '13 at 14:17
  • 1
    @Cruncher you're right, I did a look ahead, not a look behind. It should have been (?<!^)([A-Z]) and it does work, tested on http://java-regex-tester.appspot.com/. Note that regexpal.com is just a JavaScript regex tester. – Nathanial Oct 17 '13 at 14:27
  • @Nathanial The syntax on lookbehind/ahead is so ludicrously unintuitive. – Cruncher Oct 17 '13 at 14:47
  • @Nathanial, I'm finally home and I have tested my RegExp, I have updated it for a negative lookahead. – Silviu Burcea Oct 17 '13 at 17:00
  • You can even use a positive lookahead within the `(A-Z)` to get rid of the `$1` in the replacement. – nickb Oct 18 '13 at 17:23
5
public static void sep(String s) {
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {

        result.append(s.charAt(i));
        if (i != s.length() -1 && Character.isUpperCase(s.charAt(i + 1))) {
            result.append(" ");
        }
    }
    System.out.println(result);
}

Simply add a space if the next character is uppercase.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
1

Similar question here: Insert Space After Capital letter

try it and if you have any questions let us know!

the code from reference is here:

  String s = "HelloWorldNishant";
    StringBuilder out = new StringBuilder(s);
    Pattern p = Pattern.compile("[A-Z]");
    Matcher m = p.matcher(s);
    int extraFeed = 0;
    while(m.find()){
        if(m.start()!=0){
            out = out.insert(m.start()+extraFeed, " ");
            extraFeed++;
        }
    }
    System.out.println(out);
Community
  • 1
  • 1
X-Pippes
  • 1,170
  • 7
  • 25
  • This is an excellent and elegant solution. Not knowing about 'pattern' and 'matcher' makes things tough. Thanks mate everyone. – emi Oct 17 '13 at 13:39
1

Using String.replaceAll:

String foo = "SomeLongName";
System.out.println(foo.replaceAll("([a-z]+)([A-Z])", "$1 $2"));

Results in Some Long Name.

devnull
  • 118,548
  • 33
  • 236
  • 227
  • 1
    +1 Because this will not turn "Mike\sJackson" into "Mike\s\sJackson" (\s is space. SO doesn't let me put double spaces) – Cruncher Oct 17 '13 at 13:39
  • It won't work for all the cases. Word1Word2Word3 is one example, 1 is not a lowercase character and it won't add a space between 1 and W. – Silviu Burcea Oct 17 '13 at 14:24
  • @SilviuBurcea Well, OP didn't suggest that names could have digits. BTW, you could say `string.replaceAll("([a-z0-9]+)([A-Z])", "$1 $2")` for your example. – devnull Oct 17 '13 at 14:26
0

String is final and immutable, you cannot modify it, you will always use it to create a new one and assign to any variable.

Being that said, i would recommend to look for the first non-zero index uppercase, get the substring where it is located, store the two substrings and add and space between.

RamonBoza
  • 8,898
  • 6
  • 36
  • 48
  • 4
    This is misleading. String being final does not mean that I can't do: `String s = "1"; s+="2";`. It just means that I can't extend it – Cruncher Oct 17 '13 at 13:32
0

The easiest way to go round this, in this case would be to use regular expressions

    String str = "MikeJackson";
    System.out.println(str.replaceAll("(\\w+?)([A-Z])(\\w+?)", "$1 $2$3"));

Yields: Mike Jackson

npinti
  • 51,780
  • 5
  • 72
  • 96
0
public static String addSpaces(String str) {
    StringBuilder sb = new StringBuilder();
    if (str.length() == 0) return "";
    sb.append(str.charAt(0));
    for (int i = 1; i < str.length(); i++) {
        if (Character.isUpperCase(str.charAt(i))) sb.append(" ");
        sb.append(str.charAt(i));
    }
    return sb.toString();
}
ferrerverck
  • 618
  • 3
  • 9
  • 17