Я не знаком с «легким» способом обработки этого (то есть, я знаю, есть ли встроенная библиотека, которая может справиться с этим). Но один из способов сделать это - прочитать спецификацию JLS на escape-последовательностях и написать однопроходный синтаксический анализатор, который может находить и оценивать каждую управляющую последовательность. (Проверьте JLS 3.10.6 Escape Sequences for Character and String Literals).
Теперь я знаю, что есть несколько странностей, которые вы быстро забудете обрабатывать, например, восьмеричные экранизации сложны, потому что они позволяют либо 1,2, либо 3 цифры, и в каждом случае есть разные допустимые значения, когда это побег, и когда это просто целое число.
Возьмем пример строки «\ 431», это escape-выход «43», объединенный с символом «1», потому что первая цифра восьмеричного выхода равна 4 и, следовательно, не может быть трехзначным восьмеричным значением так как он разрешает [0-3] как первую цифру в этом случае.
Примерно год назад я был соавтором компилятора Java для подмножества спецификации 1.3, у которой есть escape-последовательности, а ниже я включил наш код для обработки экранов - на самом деле вы должны быть в состоянии принять этот код в буквальном смысле, как это и включить в класс Utility (возможно, бросить в кредит, если вы чувствуете, благотворительные):
private String processCharEscapes(String strVal) {
// Loop helpers
char[] chrArr = strVal.toCharArray();
StringBuilder strOut = new StringBuilder(strVal.length());
String strEsc = ""; // Escape sequence, string buffer
Character chrBuf = null; // Dangling character buffer
// Control flags
boolean inEscape = false; // In escape?
boolean cbOctal3 = true; // Can be octal 3-digit
// Parse characters
for(char c : chrArr) {
if (!inEscape) {
// Listen for start of escape sequence
if (c == '\\') {
inEscape = true; // Enter escape
strEsc = ""; // Reset escape buffer
chrBuf = null; // Reset dangling character buffer
cbOctal3 = true; // Reset cbOctal3 flag
} else {
strOut.append(c); // Save to output
}
} else {
// Determine escape termination
if (strEsc.length() == 0) { // First character
if (c >= 48 && c <= 55) { // c is a digit [0-7]
if (c > 51) { // c is a digit [4-7]
cbOctal3 = false;
}
strEsc += c; // Save to buffer
} else { // c is a character
// Single-character escapes (will terminate escape loop)
if (c == 'n') {
inEscape = false;
strOut.append('\n');
} else if(c == 't') {
inEscape = false;
strOut.append('\t');
} else if(c == 'b') {
inEscape = false;
strOut.append('\b');
} else if(c == 'r') {
inEscape = false;
strOut.append('\r');
} else if(c == 'f') {
inEscape = false;
strOut.append('\f');
} else if(c == '\\') {
inEscape = false;
strOut.append('\\');
} else if(c == '\'') {
inEscape = false;
strOut.append('\'');
} else if(c == '"') {
inEscape = false;
strOut.append('"');
} else {
// Saw illegal character, after escape character '\'
System.err.println(ErrorType.SYNTAX_ERROR, "Illegal character escape sequence, unrecognised escape: \\" + c);
}
}
} else if(strEsc.length() == 1) { // Second character (possibly)
if (c >= 48 && c <= 55) { // c is a digit [0-7]
strEsc += c; // Save to buffer
if (!cbOctal3) { // Terminate since !cbOctal3
inEscape = false;
}
} else {
inEscape = false; // Terminate since c is not a digit
chrBuf = c; // Save dangling character
}
} else if(strEsc.length() == 2) { // Third character (possibly)
if (cbOctal3 && c >= 48 && c <= 55) {
strEsc += c; // Save to buffer
} else {
chrBuf = c; // Save dangling character
}
inEscape = false; // Will always terminate after third character, no matter what
}
// Did escape sequence terminate, at character c?
if (!inEscape && strEsc.length() > 0) {
// strEsc is legal 1-3 digit octal char code, convert and add
strOut.append((char)Integer.parseInt(strEsc, 8));
if (chrBuf != null) { // There was a dangling character
// Check for chained escape sequences (e.g. \10\10)
if (chrBuf == '\\') {
inEscape = true; // Enter escape
strEsc = ""; // Reset escape buffer
chrBuf = null; // Reset dangling character buffer
cbOctal3 = true; // Reset cbOctal3 flag
} else {
strOut.append(chrBuf);
}
}
}
}
}
// Check for EOL-terminated escape sequence (special case)
if (inEscape) {
// strEsc is legal 1-3 digit octal char code, convert and add
strOut.append((char)Integer.parseInt(strEsc, 8));
if (chrBuf != null) { // There was a dangling character
strOut.append(chrBuf);
}
}
return strOut.toString();
}
Я надеюсь, что это поможет.
Можете ли вы просто использовать String.replace()? –
Хорошо за пределами \ r \ n Я бы предпочел не заменять все возможные литералы \ X и \ uXXXX и т. Д. Вручную, если это возможно –