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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | package Torello.Java; import java.util.stream.IntStream; class CharArrPrepend { static String replace( final boolean ignoreCase, final String s, final char[] matchCharsInput, final char prependChar ) { // Need a temporary 'count' variable int count = 0; // Improve the loop counter efficiency, use a 'len' instead of s.length() int len = s.length(); final char[] matchChars; if (ignoreCase) { matchChars = new char[matchCharsInput.length]; for (int i=0; i < matchChars.length; i++) matchChars[i] = Character.toLowerCase(matchCharsInput[i]); } else matchChars = matchCharsInput; // Use a Java Stream to save the locations of the matches IntStream.Builder whereB = IntStream.builder(); // Count how many escape-characters are in the input-string if (ignoreCase) TOP1: for (int i=0; i < len; i++) { char c = Character.toLowerCase(s.charAt(i)); // This checks if the character is a match with any of the match-characters in // the input array. for (char matchChar : matchChars) if (matchChar == c) { whereB.accept(i); continue TOP1; } } else TOP2: for (int i=0; i < len; i++) { char c = s.charAt(i); // This checks if the character is a match with any of the match-characters in // the input array. for (char matchChar : matchChars) if (matchChar == c) { whereB.accept(i); continue TOP2; } } // Build the java stream, and turn it into an index-pointer array (int array of // array indices) int[] whereArr = whereB.build().toArray(); // No matches, return original string. if (whereArr.length == 0) return s; // The 'escaped string' will be longer than the original String by // 'whereArr.length' characters. Use a character array to build this string char[] cArr = new char[len + whereArr.length]; // There are now three different indices to keep up with - when doing this replace. // The input-string index. The index of the "Match Locations Array" (whereArr), and the // index into the returned String - which, for now, is represented as a char[] array. int oldStrPos = 0; int newStrPos = 0; int i = 0; while (oldStrPos < len) { // The next character in the input string char c = s.charAt(oldStrPos); // Was this one of the matches - as computed in the earlier loop? if (oldStrPos == whereArr[i]) { // if "YES", then insert the prependChar, AND the original-string-char cArr[newStrPos++] = prependChar; cArr[newStrPos++] = c; // Here, increment the "Match Locations Array" index-location too. // (We have just "used up" one of the match-locations. i++; } else // if "NO", then just insert the original-string-char cArr[newStrPos++] = c; // Only at the end should we increment the input-string index-location. oldStrPos++; } // Convert the char array that was built into a String, and return it. return String.valueOf(cArr); } } |