String (@NotNull String s) { StringBuilder buffer = new StringBuilder(); int length = s.length(); int count = 0; int radix = 0; int suffixLen = 0; boolean decode = false; boolean escaped = false; for (int idx = 0; idx < length; idx++) { char ch = s.charAt(idx); if (!escaped) { if (ch == '\\') { escaped = true; } else { buffer.append(ch); } } else { switch (ch) { case '\'': buffer.append((char)0x27); break; case '\"': buffer.append((char)0x22); break; case '?': buffer.append((char)0x3f); break; case '\\': buffer.append((char)0x5c); break; case 'a': buffer.append((char)0x07); break; case 'b': buffer.append((char)0x08); break; case 'f': buffer.append((char)0x0c); break; case 'n': buffer.append((char)0x0a); break; case 'r': buffer.append((char)0x0d); break; case 't': buffer.append((char)0x09); break; case 'v': buffer.append((char)0x0b); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': count = 3; radix = 8; suffixLen = 0; decode = true; break; case 'x': count = 2; radix = 0x10; suffixLen = 1; decode = true; break; case 'u': count = 4; radix = 0x10; suffixLen = 1; decode = true; break; case 'U': count = 8; radix = 0x10; suffixLen = 1; decode = true; break; default: buffer.append(ch); break; } if (decode) { decode = false; StringBuilder sb = new StringBuilder(count); for (int pos = idx + suffixLen; pos < length && count > 0; ++pos) { char chl = s.charAt(pos); if (!(radix == 0x10 && isHexDigit(chl) || radix == 8 && isOctalDigit(chl))) { break; } sb.append(chl); --count; } if (sb.length() != 0) { try { long code = Long.parseLong(sb.toString(), radix); //noinspection AssignmentToForLoopParameter idx += sb.length() + suffixLen - 1; // todo: implement UTF-32 support buffer.append((char)code); } catch (NumberFormatException e) { buffer.append('\\').append(ch); } } else { buffer.append('\\').append(ch); } } escaped = false; } } if (escaped) buffer.append('\\'); return buffer.toString(); }