1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | package Torello.Java; class RightTrimAll { static String run(String s) { // SPECIAL-CASE: There is if (s.length() == 0) return s; char[] cArr = s.toCharArray(); int targetPos = 0; int nlPos = 0; // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Set up the Loop Variables 'nlPos' and 'targetPos' // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // SKIP: Skip past all leading new-lines. They don't need to be moved at all in the loop! for (nlPos=0; (nlPos < cArr.length) && (cArr[nlPos] == '\n'); nlPos++); // SPECIAL-CASE: The String had **ONLY** new-lines in it... if (nlPos == cArr.length) return s; // IF THERE WERE LEADING NEWLINES: // // AFTER-LOOP: 'nlPos' will be pointing at the character IMMEDIATELY-AFTER the last // leading newline. // // NOTE: IF there WERE NOT leading newlines, 'nlPos' is ZERO, // which is just fine for assigning to 'targetPos' anyway! targetPos = nlPos; // Continue to initialize 'nlPos' and 'targetPos' // // PART ONE: Find the FIRST new-line AFTER the first CONTENT-CONTAINING line. // // PART TWO: Set 'targetPos' to the last character that is non-white-space. 'targetPos' // will be incremented-by-one later to point to white-space. while ((++nlPos < cArr.length) && (cArr[nlPos] != '\n')) if (! Character.isWhitespace(cArr[nlPos])) targetPos = nlPos; // Now increment 'targetPos' because in MOST-CASES it will be pointing to the last // non-white-space character in the first line. (and we *CANNOT* clobber that character!) // // HOWEVER: if 'targetPos' is still pointing at White-Space (after the previous loop), // then it must be that the ENTIRE-FIRST-LINE was BLANK! if (! Character.isWhitespace(cArr[targetPos])) targetPos++; // SPECIAL-CASE: The first CONTENT-FUL LINE is the ONLY-LINE in the text. // // ===> Return the input-String. // **BUT** make sure to right-trim that CONTENT-FUL line. if (nlPos == cArr.length) return s.substring(0, targetPos); // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // Now do the 'Shifting Loop' // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** while (nlPos < cArr.length) { int nextNLPos = nlPos + 1; int lastNonWhiteSpacePos = nlPos; int sourcePos = nlPos; // Compute 'nextNLPos' and 'lastNonWhiteSpacePos': In the Example *SUBSTRING* Below: // "...\nHello, How are you? \n..." // // NEW-LINE-POS was set to the first '\n' you see in the above-String // The '?' is the LAST-NON-WHITE-SPACE // The '\n' after that is the NEXT-NEWLINE-POS while ((nextNLPos < cArr.length) && (cArr[nextNLPos] != '\n')) { if (! Character.isWhitespace(cArr[nextNLPos])) lastNonWhiteSpacePos = nextNLPos; nextNLPos++; } // Shift all characters BEGINNING with the OLD new-line position (since 'sourcePos') // is initiliazed with 'nlPos') ... // // AGAIN: Shift all characters beginning with 'nlPos' UP-TO-AND-INCLUDING // 'lastNonWhiteSpacePos' for the NEXT line of text to the appropriate position. while (sourcePos <= lastNonWhiteSpacePos) cArr[targetPos++] = cArr[sourcePos++]; // The next loop-iteration will start with the next line in the text. nlPos = nextNLPos; } return new String(cArr, 0, targetPos); } } |