< prev index next >

src/java.base/share/classes/java/lang/String.java

Print this page
rev 51726 : 8202442: String::unescape
Reviewed-by: smarks, rriggs, sherman


2955      *
2956      * @return string with margins removed, indentation adjusted and
2957      *         line terminators normalized
2958      *
2959      * @see String#align()
2960      *
2961      * @since 12
2962      */
2963     public String align(int n) {
2964         if (isEmpty()) {
2965             return "";
2966         }
2967         int outdent = lines().filter(not(String::isBlank))
2968                              .mapToInt(String::indexOfNonWhitespace)
2969                              .min()
2970                              .orElse(0);
2971         return indent(n - outdent, true);
2972     }
2973 
2974     /**




























































































































































































2975      * This object (which is already a string!) is itself returned.
2976      *
2977      * @return  the string itself.
2978      */
2979     public String toString() {
2980         return this;
2981     }
2982 
2983     /**
2984      * Returns a stream of {@code int} zero-extending the {@code char} values
2985      * from this sequence.  Any char which maps to a <a
2986      * href="{@docRoot}/java.base/java/lang/Character.html#unicode">surrogate code
2987      * point</a> is passed through uninterpreted.
2988      *
2989      * @return an IntStream of char values from this sequence
2990      * @since 9
2991      */
2992     @Override
2993     public IntStream chars() {
2994         return StreamSupport.intStream(




2955      *
2956      * @return string with margins removed, indentation adjusted and
2957      *         line terminators normalized
2958      *
2959      * @see String#align()
2960      *
2961      * @since 12
2962      */
2963     public String align(int n) {
2964         if (isEmpty()) {
2965             return "";
2966         }
2967         int outdent = lines().filter(not(String::isBlank))
2968                              .mapToInt(String::indexOfNonWhitespace)
2969                              .min()
2970                              .orElse(0);
2971         return indent(n - outdent, true);
2972     }
2973 
2974     /**
2975      * Translates all Unicode escapes and escape sequences in this string into
2976      * characters represented by those escapes specified in sections 3.3 and
2977      * 3.10.6 of the <cite>The Java&trade; Language Specification</cite>.
2978      * <p>
2979      * Each unicode escape in the form \unnnn is translated to a
2980      * 16-bit 'char' value.
2981      * <p>
2982      * Backslash escape sequences are translated as follows;
2983      * <table class="plain">
2984      *   <caption style="display:none">Escape sequences</caption>
2985      *   <thead>
2986      *   <tr>
2987      *     <th scope="col">Escape</th>
2988      *     <th scope="col">Name</th>
2989      *     <th scope="col">Unicode</th>
2990      *   </tr>
2991      *   </thead>
2992      *   <tr>
2993      *     <td>{@code \b}</td>
2994      *     <td>backspace</td>
2995      *     <td>U+0008</td>
2996      *   </tr>
2997      *   <tr>
2998      *     <td>{@code \t}</td>
2999      *     <td>horizontal tab</td>
3000      *     <td>U+0009</td>
3001      *   </tr>
3002      *   <tr>
3003      *     <td>{@code \n}</td>
3004      *     <td>line feed</td>
3005      *     <td>U+000A</td>
3006      *   </tr>
3007      *   <tr>
3008      *     <td>{@code \f}</td>
3009      *     <td>form feed</td>
3010      *     <td>U+000C</td>
3011      *   </tr>
3012      *   <tr>
3013      *     <td>{@code \r}</td>
3014      *     <td>carriage return</td>
3015      *     <td>U+000D</td>
3016      *   </tr>
3017      *   <tr>
3018      *     <td>{@code \"}</td>
3019      *     <td>double quote</td>
3020      *     <td>U+0022</td>
3021      *   </tr>
3022      *   <tr>
3023      *     <td>{@code \'}</td>
3024      *     <td>single quote</td>
3025      *     <td>U+0027</td>
3026      *   </tr>
3027      *   <tr>
3028      *     <td>{@code \\}</td>
3029      *     <td>backslash</td>
3030      *     <td>U+005C</td>
3031      *   </tr>
3032      * </table>
3033      * <p>
3034      * Octal escapes {@code \0 - \377} are translated to their code
3035      * point equivalents.
3036      *
3037      * @return String with all escapes translated.
3038      *
3039      * @throws IllegalArgumentException when the escape sequence does
3040      * not conform to JLS 3.3 or 3.10.6.
3041      *
3042      * @jls 3.3 Unicode escapes
3043      * @jls 3.10.6 Escape sequences
3044      *
3045      * @since 12
3046      *
3047      * @deprecated  Preview feature associated with Raw String Literals.
3048      */
3049     @Deprecated(forRemoval=true, since="12")
3050     public String unescape() {
3051         UnicodeReader reader = new UnicodeReader();
3052         int length = reader.length();
3053         char[] chars = new char[length];
3054         int to = 0;
3055         while (reader.hasNext()) {
3056             char ch = reader.next();
3057             if (ch == '\\') {
3058                 if (!reader.hasNext()) {
3059                     reader.error("truncated escape sequence");
3060                 }
3061                 ch = reader.next();
3062                 switch (ch) {
3063                     case 'b':
3064                         ch = '\b';
3065                         break;
3066                     case 'f':
3067                         ch = '\f';
3068                         break;
3069                     case 'n':
3070                         ch = '\n';
3071                         break;
3072                     case 'r':
3073                         ch = '\r';
3074                         break;
3075                     case 't':
3076                         ch = '\t';
3077                         break;
3078                     case '\\':
3079                         ch = '\\';
3080                         break;
3081                     case '\'':
3082                         ch = '\'';
3083                         break;
3084                     case '\"':
3085                         ch = '\"';
3086                         break;
3087                     case '0': case '1': case '2': case '3':
3088                     case '4': case '5': case '6': case '7':
3089                         int code = ch - '0';
3090                         for (int i = 0; i < 2 && reader.hasNext(); i++) {
3091                             int digit = Character.digit(reader.next(), 8);
3092                             if (digit < 0) {
3093                                 reader.pushBack();
3094                                 break;
3095                             }
3096                             code = code << 3 | digit;
3097                         }
3098                         if (0377 < code) {
3099                             reader.error("octal escape sequence value is too large");
3100                         }
3101                         ch = (char)code;
3102                         break;
3103                     default:
3104                         reader.error("unrecognized escape sequence");
3105                 }
3106             }
3107             chars[to++] = ch;
3108         }
3109         return new String(chars, 0, to);
3110     }
3111 
3112     private class UnicodeReader {
3113         final int length;
3114         int from;
3115         int prev;
3116 
3117         UnicodeReader() {
3118             this.length = String.this.length();
3119             this.from = 0;
3120             this.prev = 0;
3121         }
3122 
3123         int length() {
3124             return length;
3125         }
3126 
3127         boolean hasNext() {
3128             return from < length;
3129         }
3130 
3131         char next() {
3132             prev = from;
3133             char next = charAt(from++);
3134             if (next != '\\' || (hasNext() && charAt(from) != 'u')) {
3135                 return next;
3136             }
3137             do {
3138                 next = charAt(from++);
3139             } while (next == 'u' && hasNext());
3140             if (length <= from + 2) {
3141                 error("unicode escape sequence truncated at end of string");
3142             }
3143             int code = (Character.digit(next          , 16) << 12) |
3144                        (Character.digit(charAt(from++), 16) <<  8) |
3145                        (Character.digit(charAt(from++), 16) <<  4) |
3146                         Character.digit(charAt(from++), 16);
3147             if (code < 0) {
3148                 error("unicode escape sequence contains non hexadecimal digits");
3149             }
3150             return (char)code;
3151         }
3152 
3153         void pushBack() {
3154             from = prev;
3155         }
3156 
3157         void error(String message) {
3158             throw new IllegalArgumentException(message + ", pos = " + (from - 1));
3159         }
3160     }
3161 
3162     /**
3163      * This object (which is already a string!) is itself returned.
3164      *
3165      * @return  the string itself.
3166      */
3167     public String toString() {
3168         return this;
3169     }
3170 
3171     /**
3172      * Returns a stream of {@code int} zero-extending the {@code char} values
3173      * from this sequence.  Any char which maps to a <a
3174      * href="{@docRoot}/java.base/java/lang/Character.html#unicode">surrogate code
3175      * point</a> is passed through uninterpreted.
3176      *
3177      * @return an IntStream of char values from this sequence
3178      * @since 9
3179      */
3180     @Override
3181     public IntStream chars() {
3182         return StreamSupport.intStream(


< prev index next >