< 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
*** 2970,2979 ****
--- 2970,3167 ----
.orElse(0);
return indent(n - outdent, true);
}
/**
+ * Translates all Unicode escapes and escape sequences in this string into
+ * characters represented by those escapes specified in sections 3.3 and
+ * 3.10.6 of the <cite>The Java™ Language Specification</cite>.
+ * <p>
+ * Each unicode escape in the form \unnnn is translated to a
+ * 16-bit 'char' value.
+ * <p>
+ * Backslash escape sequences are translated as follows;
+ * <table class="plain">
+ * <caption style="display:none">Escape sequences</caption>
+ * <thead>
+ * <tr>
+ * <th scope="col">Escape</th>
+ * <th scope="col">Name</th>
+ * <th scope="col">Unicode</th>
+ * </tr>
+ * </thead>
+ * <tr>
+ * <td>{@code \b}</td>
+ * <td>backspace</td>
+ * <td>U+0008</td>
+ * </tr>
+ * <tr>
+ * <td>{@code \t}</td>
+ * <td>horizontal tab</td>
+ * <td>U+0009</td>
+ * </tr>
+ * <tr>
+ * <td>{@code \n}</td>
+ * <td>line feed</td>
+ * <td>U+000A</td>
+ * </tr>
+ * <tr>
+ * <td>{@code \f}</td>
+ * <td>form feed</td>
+ * <td>U+000C</td>
+ * </tr>
+ * <tr>
+ * <td>{@code \r}</td>
+ * <td>carriage return</td>
+ * <td>U+000D</td>
+ * </tr>
+ * <tr>
+ * <td>{@code \"}</td>
+ * <td>double quote</td>
+ * <td>U+0022</td>
+ * </tr>
+ * <tr>
+ * <td>{@code \'}</td>
+ * <td>single quote</td>
+ * <td>U+0027</td>
+ * </tr>
+ * <tr>
+ * <td>{@code \\}</td>
+ * <td>backslash</td>
+ * <td>U+005C</td>
+ * </tr>
+ * </table>
+ * <p>
+ * Octal escapes {@code \0 - \377} are translated to their code
+ * point equivalents.
+ *
+ * @return String with all escapes translated.
+ *
+ * @throws IllegalArgumentException when the escape sequence does
+ * not conform to JLS 3.3 or 3.10.6.
+ *
+ * @jls 3.3 Unicode escapes
+ * @jls 3.10.6 Escape sequences
+ *
+ * @since 12
+ *
+ * @deprecated Preview feature associated with Raw String Literals.
+ */
+ @Deprecated(forRemoval=true, since="12")
+ public String unescape() {
+ UnicodeReader reader = new UnicodeReader();
+ int length = reader.length();
+ char[] chars = new char[length];
+ int to = 0;
+ while (reader.hasNext()) {
+ char ch = reader.next();
+ if (ch == '\\') {
+ if (!reader.hasNext()) {
+ reader.error("truncated escape sequence");
+ }
+ ch = reader.next();
+ switch (ch) {
+ case 'b':
+ ch = '\b';
+ break;
+ case 'f':
+ ch = '\f';
+ break;
+ case 'n':
+ ch = '\n';
+ break;
+ case 'r':
+ ch = '\r';
+ break;
+ case 't':
+ ch = '\t';
+ break;
+ case '\\':
+ ch = '\\';
+ break;
+ case '\'':
+ ch = '\'';
+ break;
+ case '\"':
+ ch = '\"';
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ int code = ch - '0';
+ for (int i = 0; i < 2 && reader.hasNext(); i++) {
+ int digit = Character.digit(reader.next(), 8);
+ if (digit < 0) {
+ reader.pushBack();
+ break;
+ }
+ code = code << 3 | digit;
+ }
+ if (0377 < code) {
+ reader.error("octal escape sequence value is too large");
+ }
+ ch = (char)code;
+ break;
+ default:
+ reader.error("unrecognized escape sequence");
+ }
+ }
+ chars[to++] = ch;
+ }
+ return new String(chars, 0, to);
+ }
+
+ private class UnicodeReader {
+ final int length;
+ int from;
+ int prev;
+
+ UnicodeReader() {
+ this.length = String.this.length();
+ this.from = 0;
+ this.prev = 0;
+ }
+
+ int length() {
+ return length;
+ }
+
+ boolean hasNext() {
+ return from < length;
+ }
+
+ char next() {
+ prev = from;
+ char next = charAt(from++);
+ if (next != '\\' || (hasNext() && charAt(from) != 'u')) {
+ return next;
+ }
+ do {
+ next = charAt(from++);
+ } while (next == 'u' && hasNext());
+ if (length <= from + 2) {
+ error("unicode escape sequence truncated at end of string");
+ }
+ int code = (Character.digit(next , 16) << 12) |
+ (Character.digit(charAt(from++), 16) << 8) |
+ (Character.digit(charAt(from++), 16) << 4) |
+ Character.digit(charAt(from++), 16);
+ if (code < 0) {
+ error("unicode escape sequence contains non hexadecimal digits");
+ }
+ return (char)code;
+ }
+
+ void pushBack() {
+ from = prev;
+ }
+
+ void error(String message) {
+ throw new IllegalArgumentException(message + ", pos = " + (from - 1));
+ }
+ }
+
+ /**
* This object (which is already a string!) is itself returned.
*
* @return the string itself.
*/
public String toString() {
< prev index next >