Java Programming: Replace all but first and last letters of each word with “_”How do I efficiently iterate over each entry in a Java Map?How does the Java 'for each' loop work?Including all the jars in a directory within the Java classpathHow to capitalize the first character of each word in a stringView if a word's letters are in ascending orderDoubling each letter in a StringHow to have an input of letters and change them to uppercase and lower case? JAVASomething going wrong with the charAt method?checking if first char is equal to last charMy do while loop isn't working?

Is "remove commented out code" correct English?

A category-like structure without composition?

Reverse dictionary where values are lists

How do I gain back my faith in my PhD degree?

How seriously should I take size and weight limits of hand luggage?

Solving a recurrence relation (poker chips)

Why didn't Miles's spider sense work before?

How can saying a song's name be a copyright violation?

Forgetting the musical notes while performing in concert

Can I run a new neutral wire to repair a broken circuit?

What is a romance in Latin?

Cursor Replacement for Newbies

What reasons are there for a Capitalist to oppose a 100% inheritance tax?

How badly should I try to prevent a user from XSSing themselves?

Would Slavery Reparations be considered Bills of Attainder and hence Illegal?

ssTTsSTtRrriinInnnnNNNIiinngg

What method can I use to design a dungeon difficult enough that the PCs can't make it through without killing them?

Why is it a bad idea to hire a hitman to eliminate most corrupt politicians?

CAST throwing error when run in stored procedure but not when run as raw query

Why would the Red Woman birth a shadow if she worshipped the Lord of the Light?

Why can't we play rap on piano?

Avoiding the "not like other girls" trope?

Assassin's bullet with mercury

Why no variance term in Bayesian logistic regression?



Java Programming: Replace all but first and last letters of each word with “_”


How do I efficiently iterate over each entry in a Java Map?How does the Java 'for each' loop work?Including all the jars in a directory within the Java classpathHow to capitalize the first character of each word in a stringView if a word's letters are in ascending orderDoubling each letter in a StringHow to have an input of letters and change them to uppercase and lower case? JAVASomething going wrong with the charAt method?checking if first char is equal to last charMy do while loop isn't working?













3















The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.



EDIT: How do I make this method without using arrays or extra methods, like the split method?



public static String blankWords(String s1) 

StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;


sb.append(s1.charAt(s1.length() - 1));
return sb.toString();

return s1;



What my code is outputting:




HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)




What my code should output:




HW2.blankWords("This is a Test.")
"T__s is a T__t."











share|improve this question
























  • Well, this while(y != s1.charAt(x)) can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.

    – Tom
    Mar 7 at 23:00











  • Do you know what StringIndexOutOfBoundsException means?

    – Paul Wostenberg
    Mar 7 at 23:03











  • When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence

    – Asthmatic
    Mar 7 at 23:11











  • @Tom i was drunk. Embarrasing. You were so right.

    – aran
    Mar 7 at 23:22















3















The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.



EDIT: How do I make this method without using arrays or extra methods, like the split method?



public static String blankWords(String s1) 

StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;


sb.append(s1.charAt(s1.length() - 1));
return sb.toString();

return s1;



What my code is outputting:




HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)




What my code should output:




HW2.blankWords("This is a Test.")
"T__s is a T__t."











share|improve this question
























  • Well, this while(y != s1.charAt(x)) can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.

    – Tom
    Mar 7 at 23:00











  • Do you know what StringIndexOutOfBoundsException means?

    – Paul Wostenberg
    Mar 7 at 23:03











  • When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence

    – Asthmatic
    Mar 7 at 23:11











  • @Tom i was drunk. Embarrasing. You were so right.

    – aran
    Mar 7 at 23:22













3












3








3


2






The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.



EDIT: How do I make this method without using arrays or extra methods, like the split method?



public static String blankWords(String s1) 

StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;


sb.append(s1.charAt(s1.length() - 1));
return sb.toString();

return s1;



What my code is outputting:




HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)




What my code should output:




HW2.blankWords("This is a Test.")
"T__s is a T__t."











share|improve this question
















The purpose of this method is replace all but the first and last letters of each word with "_". I'm a complete novice when it comes to coding, so I'm certain my code is fairly incorrect. I think where my code starts functioning improperly is with the while loop.



EDIT: How do I make this method without using arrays or extra methods, like the split method?



public static String blankWords(String s1) 

StringBuilder sb = new StringBuilder();
if(s1.length() > 2)
sb.append(s1.charAt(0));
for(int x = 1; x < s1.length() - 1; x = x + 1)
char y = ' ';
while(y != s1.charAt(x))
sb.append("_");
x = x + 1;


sb.append(s1.charAt(s1.length() - 1));
return sb.toString();

return s1;



What my code is outputting:




HW2.blankWords("This is a Test.")
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.charAt(Unknown Source)
at HW2.blankWords(HW2.java:73)




What my code should output:




HW2.blankWords("This is a Test.")
"T__s is a T__t."








java






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 7 at 23:24







user11168053

















asked Mar 7 at 22:56









user11168053user11168053

155




155












  • Well, this while(y != s1.charAt(x)) can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.

    – Tom
    Mar 7 at 23:00











  • Do you know what StringIndexOutOfBoundsException means?

    – Paul Wostenberg
    Mar 7 at 23:03











  • When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence

    – Asthmatic
    Mar 7 at 23:11











  • @Tom i was drunk. Embarrasing. You were so right.

    – aran
    Mar 7 at 23:22

















  • Well, this while(y != s1.charAt(x)) can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.

    – Tom
    Mar 7 at 23:00











  • Do you know what StringIndexOutOfBoundsException means?

    – Paul Wostenberg
    Mar 7 at 23:03











  • When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence

    – Asthmatic
    Mar 7 at 23:11











  • @Tom i was drunk. Embarrasing. You were so right.

    – aran
    Mar 7 at 23:22
















Well, this while(y != s1.charAt(x)) can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.

– Tom
Mar 7 at 23:00





Well, this while(y != s1.charAt(x)) can't work when the program already treats the last word. There is no more whitespace to exit the loop. So you need to add another exit condition.

– Tom
Mar 7 at 23:00













Do you know what StringIndexOutOfBoundsException means?

– Paul Wostenberg
Mar 7 at 23:03





Do you know what StringIndexOutOfBoundsException means?

– Paul Wostenberg
Mar 7 at 23:03













When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence

– Asthmatic
Mar 7 at 23:11





When you say HW2.blankWords("This is a Test.") should output "T__s is a T__t.", do you mean to include that period? it doesn't look like your code makes any attempt to keep a period at the end of the sentence

– Asthmatic
Mar 7 at 23:11













@Tom i was drunk. Embarrasing. You were so right.

– aran
Mar 7 at 23:22





@Tom i was drunk. Embarrasing. You were so right.

– aran
Mar 7 at 23:22












4 Answers
4






active

oldest

votes


















0














Here is a pretty simple solution:



class Scratch 
public static void main(String[] args)
System.out.println(blankWords("My name is sam orozco"));


public static String delim = "_";

public static String blankWords(String s1)
// this split arg on one or more space
String[] words = s1.split("\s+");
StringBuilder response = new StringBuilder();
for (String val : words)
val = convertWord(val);
response.append(val).append(" ");

return response.toString().trim();



public static String convertWord(String val)
int len = val.length();
StringBuilder bldr = new StringBuilder();
int index = 0;
for (char ch : val.toCharArray()) index == len - 1)
bldr.append(ch);
else
bldr.append(delim);

index++;

return bldr.toString();







share|improve this answer






























    0














    You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:



    String blankWords(String s) 
    // build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
    StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
    // a helper class to build the output string; think of it as just a more efficient concat utility
    StringBuilder sb = new StringBuilder();
    while (tokenizer.hasMoreTokens())
    String blankWord = blank(tokenizer.nextToken());
    sb.append(blankWord);

    return sb.toString();


    /**
    * Replaces all but the first and last characters in a string with '_'
    */
    private String blank(String word)
    // strings of up to two chars will be returned as such
    // delimiters will always fall into this category, as they are always single characters
    if (word.length() <= 2)
    return word;

    // no need to iterate through all chars, we'll just get the array
    final char[] chars = word.toCharArray();
    // fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
    Arrays.fill(chars, 1, chars.length - 1, '_');
    // build the resulting word based on the modified array of chars
    return new String(chars);



    Here is the contents of a test that validates this implementation, using TestNG:



    @Test(dataProvider = "texts")
    public void testBlankWords(String input, String expectedOutput)
    assertEquals(blankWords(input), expectedOutput);


    @DataProvider
    public Object[][] texts()
    return new Object[][]
    "This is a test.", "T__s is a t__t.",
    "This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
    ;



    The main drawback of this implementation is that StringTokenizer requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false for Character.isAlphabetic(c) or however you decide to define your non-word chars.




    P.S.
    This could be a "more advanced implementation", as I mentioned above:



    static String blankWords(String text) 
    final char[] textChars = text.toCharArray();
    int wordStart = -1; // keep track of the current word start position, -1 means no current word
    for (int i = 0; i < textChars.length; i++)
    if (!Character.isAlphabetic(textChars[i]))
    if (wordStart >= 0)
    for (int j = wordStart + 1; j < i - 1; j++)
    textChars[j] = '_';


    wordStart = -1; // reset the current word to none
    else if (wordStart == -1)
    wordStart = i; // alphabetic characters start a new word, when there's none started already
    else if (i == textChars.length - 1) // if the last character is aplhabetic
    for (int j = wordStart + 1; j < i; j++)
    textChars[j] = '_';



    return new String(textChars);






    share|improve this answer
































      -1














      No while loop necessary!



      Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).



      Always add the last character



      public static String blankWords(String s1) 
      StringBuilder sb = new StringBuilder();
      if(s1.length() > 2)
      Boolean skipNext = false;
      for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
      sb.append(s1.charAt(x));
      skipNext = false;

      else
      if(skipNext)
      sb.append('_');

      else
      sb.append(s1.charAt(x));
      skipNext = true;




      sb.append(s1.charAt(s1.length() - 1));
      return sb.toString();

      return s1;






      share|improve this answer























      • For input "This is a Test.", that returns "T__s is a T___.", but it is expected to return "T__s is a T__t.". --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch).

        – Andreas
        Mar 7 at 23:16



















      -2














      For the more advanced programmer, use regular expression.



      public static String blankWords(String s1) 
      return s1.replaceAll("\B\w\B", "_");



      This correctly keeps the final t, i.e. blankWords("This is a Test.") returns "T__s is a T__t.".






      share|improve this answer

























        Your Answer






        StackExchange.ifUsing("editor", function ()
        StackExchange.using("externalEditor", function ()
        StackExchange.using("snippets", function ()
        StackExchange.snippets.init();
        );
        );
        , "code-snippets");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "1"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );













        draft saved

        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054128%2fjava-programming-replace-all-but-first-and-last-letters-of-each-word-with%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        0














        Here is a pretty simple solution:



        class Scratch 
        public static void main(String[] args)
        System.out.println(blankWords("My name is sam orozco"));


        public static String delim = "_";

        public static String blankWords(String s1)
        // this split arg on one or more space
        String[] words = s1.split("\s+");
        StringBuilder response = new StringBuilder();
        for (String val : words)
        val = convertWord(val);
        response.append(val).append(" ");

        return response.toString().trim();



        public static String convertWord(String val)
        int len = val.length();
        StringBuilder bldr = new StringBuilder();
        int index = 0;
        for (char ch : val.toCharArray()) index == len - 1)
        bldr.append(ch);
        else
        bldr.append(delim);

        index++;

        return bldr.toString();







        share|improve this answer



























          0














          Here is a pretty simple solution:



          class Scratch 
          public static void main(String[] args)
          System.out.println(blankWords("My name is sam orozco"));


          public static String delim = "_";

          public static String blankWords(String s1)
          // this split arg on one or more space
          String[] words = s1.split("\s+");
          StringBuilder response = new StringBuilder();
          for (String val : words)
          val = convertWord(val);
          response.append(val).append(" ");

          return response.toString().trim();



          public static String convertWord(String val)
          int len = val.length();
          StringBuilder bldr = new StringBuilder();
          int index = 0;
          for (char ch : val.toCharArray()) index == len - 1)
          bldr.append(ch);
          else
          bldr.append(delim);

          index++;

          return bldr.toString();







          share|improve this answer

























            0












            0








            0







            Here is a pretty simple solution:



            class Scratch 
            public static void main(String[] args)
            System.out.println(blankWords("My name is sam orozco"));


            public static String delim = "_";

            public static String blankWords(String s1)
            // this split arg on one or more space
            String[] words = s1.split("\s+");
            StringBuilder response = new StringBuilder();
            for (String val : words)
            val = convertWord(val);
            response.append(val).append(" ");

            return response.toString().trim();



            public static String convertWord(String val)
            int len = val.length();
            StringBuilder bldr = new StringBuilder();
            int index = 0;
            for (char ch : val.toCharArray()) index == len - 1)
            bldr.append(ch);
            else
            bldr.append(delim);

            index++;

            return bldr.toString();







            share|improve this answer













            Here is a pretty simple solution:



            class Scratch 
            public static void main(String[] args)
            System.out.println(blankWords("My name is sam orozco"));


            public static String delim = "_";

            public static String blankWords(String s1)
            // this split arg on one or more space
            String[] words = s1.split("\s+");
            StringBuilder response = new StringBuilder();
            for (String val : words)
            val = convertWord(val);
            response.append(val).append(" ");

            return response.toString().trim();



            public static String convertWord(String val)
            int len = val.length();
            StringBuilder bldr = new StringBuilder();
            int index = 0;
            for (char ch : val.toCharArray()) index == len - 1)
            bldr.append(ch);
            else
            bldr.append(delim);

            index++;

            return bldr.toString();








            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 7 at 23:50









            Sam OrozcoSam Orozco

            929919




            929919























                0














                You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:



                String blankWords(String s) 
                // build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
                StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
                // a helper class to build the output string; think of it as just a more efficient concat utility
                StringBuilder sb = new StringBuilder();
                while (tokenizer.hasMoreTokens())
                String blankWord = blank(tokenizer.nextToken());
                sb.append(blankWord);

                return sb.toString();


                /**
                * Replaces all but the first and last characters in a string with '_'
                */
                private String blank(String word)
                // strings of up to two chars will be returned as such
                // delimiters will always fall into this category, as they are always single characters
                if (word.length() <= 2)
                return word;

                // no need to iterate through all chars, we'll just get the array
                final char[] chars = word.toCharArray();
                // fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
                Arrays.fill(chars, 1, chars.length - 1, '_');
                // build the resulting word based on the modified array of chars
                return new String(chars);



                Here is the contents of a test that validates this implementation, using TestNG:



                @Test(dataProvider = "texts")
                public void testBlankWords(String input, String expectedOutput)
                assertEquals(blankWords(input), expectedOutput);


                @DataProvider
                public Object[][] texts()
                return new Object[][]
                "This is a test.", "T__s is a t__t.",
                "This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
                ;



                The main drawback of this implementation is that StringTokenizer requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false for Character.isAlphabetic(c) or however you decide to define your non-word chars.




                P.S.
                This could be a "more advanced implementation", as I mentioned above:



                static String blankWords(String text) 
                final char[] textChars = text.toCharArray();
                int wordStart = -1; // keep track of the current word start position, -1 means no current word
                for (int i = 0; i < textChars.length; i++)
                if (!Character.isAlphabetic(textChars[i]))
                if (wordStart >= 0)
                for (int j = wordStart + 1; j < i - 1; j++)
                textChars[j] = '_';


                wordStart = -1; // reset the current word to none
                else if (wordStart == -1)
                wordStart = i; // alphabetic characters start a new word, when there's none started already
                else if (i == textChars.length - 1) // if the last character is aplhabetic
                for (int j = wordStart + 1; j < i; j++)
                textChars[j] = '_';



                return new String(textChars);






                share|improve this answer





























                  0














                  You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:



                  String blankWords(String s) 
                  // build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
                  StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
                  // a helper class to build the output string; think of it as just a more efficient concat utility
                  StringBuilder sb = new StringBuilder();
                  while (tokenizer.hasMoreTokens())
                  String blankWord = blank(tokenizer.nextToken());
                  sb.append(blankWord);

                  return sb.toString();


                  /**
                  * Replaces all but the first and last characters in a string with '_'
                  */
                  private String blank(String word)
                  // strings of up to two chars will be returned as such
                  // delimiters will always fall into this category, as they are always single characters
                  if (word.length() <= 2)
                  return word;

                  // no need to iterate through all chars, we'll just get the array
                  final char[] chars = word.toCharArray();
                  // fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
                  Arrays.fill(chars, 1, chars.length - 1, '_');
                  // build the resulting word based on the modified array of chars
                  return new String(chars);



                  Here is the contents of a test that validates this implementation, using TestNG:



                  @Test(dataProvider = "texts")
                  public void testBlankWords(String input, String expectedOutput)
                  assertEquals(blankWords(input), expectedOutput);


                  @DataProvider
                  public Object[][] texts()
                  return new Object[][]
                  "This is a test.", "T__s is a t__t.",
                  "This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
                  ;



                  The main drawback of this implementation is that StringTokenizer requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false for Character.isAlphabetic(c) or however you decide to define your non-word chars.




                  P.S.
                  This could be a "more advanced implementation", as I mentioned above:



                  static String blankWords(String text) 
                  final char[] textChars = text.toCharArray();
                  int wordStart = -1; // keep track of the current word start position, -1 means no current word
                  for (int i = 0; i < textChars.length; i++)
                  if (!Character.isAlphabetic(textChars[i]))
                  if (wordStart >= 0)
                  for (int j = wordStart + 1; j < i - 1; j++)
                  textChars[j] = '_';


                  wordStart = -1; // reset the current word to none
                  else if (wordStart == -1)
                  wordStart = i; // alphabetic characters start a new word, when there's none started already
                  else if (i == textChars.length - 1) // if the last character is aplhabetic
                  for (int j = wordStart + 1; j < i; j++)
                  textChars[j] = '_';



                  return new String(textChars);






                  share|improve this answer



























                    0












                    0








                    0







                    You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:



                    String blankWords(String s) 
                    // build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
                    StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
                    // a helper class to build the output string; think of it as just a more efficient concat utility
                    StringBuilder sb = new StringBuilder();
                    while (tokenizer.hasMoreTokens())
                    String blankWord = blank(tokenizer.nextToken());
                    sb.append(blankWord);

                    return sb.toString();


                    /**
                    * Replaces all but the first and last characters in a string with '_'
                    */
                    private String blank(String word)
                    // strings of up to two chars will be returned as such
                    // delimiters will always fall into this category, as they are always single characters
                    if (word.length() <= 2)
                    return word;

                    // no need to iterate through all chars, we'll just get the array
                    final char[] chars = word.toCharArray();
                    // fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
                    Arrays.fill(chars, 1, chars.length - 1, '_');
                    // build the resulting word based on the modified array of chars
                    return new String(chars);



                    Here is the contents of a test that validates this implementation, using TestNG:



                    @Test(dataProvider = "texts")
                    public void testBlankWords(String input, String expectedOutput)
                    assertEquals(blankWords(input), expectedOutput);


                    @DataProvider
                    public Object[][] texts()
                    return new Object[][]
                    "This is a test.", "T__s is a t__t.",
                    "This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
                    ;



                    The main drawback of this implementation is that StringTokenizer requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false for Character.isAlphabetic(c) or however you decide to define your non-word chars.




                    P.S.
                    This could be a "more advanced implementation", as I mentioned above:



                    static String blankWords(String text) 
                    final char[] textChars = text.toCharArray();
                    int wordStart = -1; // keep track of the current word start position, -1 means no current word
                    for (int i = 0; i < textChars.length; i++)
                    if (!Character.isAlphabetic(textChars[i]))
                    if (wordStart >= 0)
                    for (int j = wordStart + 1; j < i - 1; j++)
                    textChars[j] = '_';


                    wordStart = -1; // reset the current word to none
                    else if (wordStart == -1)
                    wordStart = i; // alphabetic characters start a new word, when there's none started already
                    else if (i == textChars.length - 1) // if the last character is aplhabetic
                    for (int j = wordStart + 1; j < i; j++)
                    textChars[j] = '_';



                    return new String(textChars);






                    share|improve this answer















                    You can do this using a StringTokenizer that will extract words based on a list of delimiters. Since you want to keep those delimiters in the output, you'll instruct the tokenizer to return them as tokens:



                    String blankWords(String s) 
                    // build a tokenizer for your string, listing all special chars as delimiters. The last argument says that delimiters are going to be returned as tokens themselves (so we can include them in the output string)
                    StringTokenizer tokenizer = new StringTokenizer(s, " .,;:?!()[]", true);
                    // a helper class to build the output string; think of it as just a more efficient concat utility
                    StringBuilder sb = new StringBuilder();
                    while (tokenizer.hasMoreTokens())
                    String blankWord = blank(tokenizer.nextToken());
                    sb.append(blankWord);

                    return sb.toString();


                    /**
                    * Replaces all but the first and last characters in a string with '_'
                    */
                    private String blank(String word)
                    // strings of up to two chars will be returned as such
                    // delimiters will always fall into this category, as they are always single characters
                    if (word.length() <= 2)
                    return word;

                    // no need to iterate through all chars, we'll just get the array
                    final char[] chars = word.toCharArray();
                    // fill the array of chars with '_', starting with position 1 (the second char) up to the last char (exclusive, i.e. last-but-one)
                    Arrays.fill(chars, 1, chars.length - 1, '_');
                    // build the resulting word based on the modified array of chars
                    return new String(chars);



                    Here is the contents of a test that validates this implementation, using TestNG:



                    @Test(dataProvider = "texts")
                    public void testBlankWords(String input, String expectedOutput)
                    assertEquals(blankWords(input), expectedOutput);


                    @DataProvider
                    public Object[][] texts()
                    return new Object[][]
                    "This is a test.", "T__s is a t__t.",
                    "This one, again, is (yet another) test!", "T__s o_e, a___n, is (y_t a_____r) t__t!"
                    ;



                    The main drawback of this implementation is that StringTokenizer requires you to list all the delimiters by hand. With a more advanced implementation, you can consider a delimiter any character that returns false for Character.isAlphabetic(c) or however you decide to define your non-word chars.




                    P.S.
                    This could be a "more advanced implementation", as I mentioned above:



                    static String blankWords(String text) 
                    final char[] textChars = text.toCharArray();
                    int wordStart = -1; // keep track of the current word start position, -1 means no current word
                    for (int i = 0; i < textChars.length; i++)
                    if (!Character.isAlphabetic(textChars[i]))
                    if (wordStart >= 0)
                    for (int j = wordStart + 1; j < i - 1; j++)
                    textChars[j] = '_';


                    wordStart = -1; // reset the current word to none
                    else if (wordStart == -1)
                    wordStart = i; // alphabetic characters start a new word, when there's none started already
                    else if (i == textChars.length - 1) // if the last character is aplhabetic
                    for (int j = wordStart + 1; j < i; j++)
                    textChars[j] = '_';



                    return new String(textChars);







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Mar 8 at 14:55

























                    answered Mar 7 at 23:53









                    Costi CiudatuCosti Ciudatu

                    28.3k54582




                    28.3k54582





















                        -1














                        No while loop necessary!



                        Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).



                        Always add the last character



                        public static String blankWords(String s1) 
                        StringBuilder sb = new StringBuilder();
                        if(s1.length() > 2)
                        Boolean skipNext = false;
                        for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
                        sb.append(s1.charAt(x));
                        skipNext = false;

                        else
                        if(skipNext)
                        sb.append('_');

                        else
                        sb.append(s1.charAt(x));
                        skipNext = true;




                        sb.append(s1.charAt(s1.length() - 1));
                        return sb.toString();

                        return s1;






                        share|improve this answer























                        • For input "This is a Test.", that returns "T__s is a T___.", but it is expected to return "T__s is a T__t.". --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch).

                          – Andreas
                          Mar 7 at 23:16
















                        -1














                        No while loop necessary!



                        Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).



                        Always add the last character



                        public static String blankWords(String s1) 
                        StringBuilder sb = new StringBuilder();
                        if(s1.length() > 2)
                        Boolean skipNext = false;
                        for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
                        sb.append(s1.charAt(x));
                        skipNext = false;

                        else
                        if(skipNext)
                        sb.append('_');

                        else
                        sb.append(s1.charAt(x));
                        skipNext = true;




                        sb.append(s1.charAt(s1.length() - 1));
                        return sb.toString();

                        return s1;






                        share|improve this answer























                        • For input "This is a Test.", that returns "T__s is a T___.", but it is expected to return "T__s is a T__t.". --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch).

                          – Andreas
                          Mar 7 at 23:16














                        -1












                        -1








                        -1







                        No while loop necessary!



                        Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).



                        Always add the last character



                        public static String blankWords(String s1) 
                        StringBuilder sb = new StringBuilder();
                        if(s1.length() > 2)
                        Boolean skipNext = false;
                        for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
                        sb.append(s1.charAt(x));
                        skipNext = false;

                        else
                        if(skipNext)
                        sb.append('_');

                        else
                        sb.append(s1.charAt(x));
                        skipNext = true;




                        sb.append(s1.charAt(s1.length() - 1));
                        return sb.toString();

                        return s1;






                        share|improve this answer













                        No while loop necessary!



                        Look ahead by 1 character to see if it's a space, or if the current character is a space, in that case you append it. Otherwise you make sure to add the next character (skipNext false).



                        Always add the last character



                        public static String blankWords(String s1) 
                        StringBuilder sb = new StringBuilder();
                        if(s1.length() > 2)
                        Boolean skipNext = false;
                        for(int x = 0; x < s1.length() - 1; x = x + 1) s1.charAt(x + 1) == ' ')
                        sb.append(s1.charAt(x));
                        skipNext = false;

                        else
                        if(skipNext)
                        sb.append('_');

                        else
                        sb.append(s1.charAt(x));
                        skipNext = true;




                        sb.append(s1.charAt(s1.length() - 1));
                        return sb.toString();

                        return s1;







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Mar 7 at 23:09









                        AsthmaticAsthmatic

                        1,025619




                        1,025619












                        • For input "This is a Test.", that returns "T__s is a T___.", but it is expected to return "T__s is a T__t.". --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch).

                          – Andreas
                          Mar 7 at 23:16


















                        • For input "This is a Test.", that returns "T__s is a T___.", but it is expected to return "T__s is a T__t.". --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch).

                          – Andreas
                          Mar 7 at 23:16

















                        For input "This is a Test.", that returns "T__s is a T___.", but it is expected to return "T__s is a T__t.". --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch).

                        – Andreas
                        Mar 7 at 23:16






                        For input "This is a Test.", that returns "T__s is a T___.", but it is expected to return "T__s is a T__t.". --- Instead of testing for space, reverse the check and test for letter, e.g. using Character.isLetter(char ch).

                        – Andreas
                        Mar 7 at 23:16












                        -2














                        For the more advanced programmer, use regular expression.



                        public static String blankWords(String s1) 
                        return s1.replaceAll("\B\w\B", "_");



                        This correctly keeps the final t, i.e. blankWords("This is a Test.") returns "T__s is a T__t.".






                        share|improve this answer





























                          -2














                          For the more advanced programmer, use regular expression.



                          public static String blankWords(String s1) 
                          return s1.replaceAll("\B\w\B", "_");



                          This correctly keeps the final t, i.e. blankWords("This is a Test.") returns "T__s is a T__t.".






                          share|improve this answer



























                            -2












                            -2








                            -2







                            For the more advanced programmer, use regular expression.



                            public static String blankWords(String s1) 
                            return s1.replaceAll("\B\w\B", "_");



                            This correctly keeps the final t, i.e. blankWords("This is a Test.") returns "T__s is a T__t.".






                            share|improve this answer















                            For the more advanced programmer, use regular expression.



                            public static String blankWords(String s1) 
                            return s1.replaceAll("\B\w\B", "_");



                            This correctly keeps the final t, i.e. blankWords("This is a Test.") returns "T__s is a T__t.".







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Mar 7 at 23:22

























                            answered Mar 7 at 23:17









                            AndreasAndreas

                            79.6k465129




                            79.6k465129



























                                draft saved

                                draft discarded
















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55054128%2fjava-programming-replace-all-but-first-and-last-letters-of-each-word-with%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Save data to MySQL database using ExtJS and PHP [closed]2019 Community Moderator ElectionHow can I prevent SQL injection in PHP?Which MySQL data type to use for storing boolean valuesPHP: Delete an element from an arrayHow do I connect to a MySQL Database in Python?Should I use the datetime or timestamp data type in MySQL?How to get a list of MySQL user accountsHow Do You Parse and Process HTML/XML in PHP?Reference — What does this symbol mean in PHP?How does PHP 'foreach' actually work?Why shouldn't I use mysql_* functions in PHP?

                                Compiling GNU Global with universal-ctags support Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Tags for Emacs: Relationship between etags, ebrowse, cscope, GNU Global and exuberant ctagsVim and Ctags tips and trickscscope or ctags why choose one over the other?scons and ctagsctags cannot open option file “.ctags”Adding tag scopes in universal-ctagsShould I use Universal-ctags?Universal ctags on WindowsHow do I install GNU Global with universal ctags support using Homebrew?Universal ctags with emacsHow to highlight ctags generated by Universal Ctags in Vim?

                                Add ONERROR event to image from jsp tldHow to add an image to a JPanel?Saving image from PHP URLHTML img scalingCheck if an image is loaded (no errors) with jQueryHow to force an <img> to take up width, even if the image is not loadedHow do I populate hidden form field with a value set in Spring ControllerStyling Raw elements Generated from JSP tagds with Jquery MobileLimit resizing of images with explicitly set width and height attributeserror TLD use in a jsp fileJsp tld files cannot be resolved