解释Java字符串
是否有任何方法可以将诸如“hello\r\n\world”之类的字符串解释为\r\n已转换为实际文字值的字符串解释Java字符串,java,regex,string,Java,Regex,String,是否有任何方法可以将诸如“hello\r\n\world”之类的字符串解释为\r\n已转换为实际文字值的字符串 该场景是用户在正则表达式替换表达式中键入,并在UI中键入。该get已转义,但我希望从中获取实际的解释字符串。我不太熟悉处理此问题的“简单”方法(即,我注意到是否有一个内置库可以处理此问题)。 但其中一种方法是阅读关于转义序列的JLS规范并编写一个单过程解析器,它可以找到并计算每个转义序列。(检查JLS) 现在我知道了一个事实,有一些奇怪的事情,你很快就会忘记处理,例如八进制转义是很棘手
该场景是用户在正则表达式替换表达式中键入,并在UI中键入。该get已转义,但我希望从中获取实际的解释字符串。我不太熟悉处理此问题的“简单”方法(即,我注意到是否有一个内置库可以处理此问题)。 但其中一种方法是阅读关于转义序列的JLS规范并编写一个单过程解析器,它可以找到并计算每个转义序列。(检查JLS) 现在我知道了一个事实,有一些奇怪的事情,你很快就会忘记处理,例如八进制转义是很棘手的,因为它允许1、2或3位数字,在每种情况下,当它是转义时,和当它只是整数时,都有不同的允许值 以字符串“\431”为例,这是与字符“1”相连的局部转义“\43”,因为八进制转义的第一个数字是4,因此不能是完整的三位数八进制值,因为在这种情况下,它只允许[0-3]作为第一个数字 大约一年前,我正在为1.3规范的一个子集共同编写一个Java编译器,它确实有转义序列,下面我已经包含了我们处理转义的代码——实际上,您应该能够按照字面意思理解这段代码,并将其包含在实用程序类中(如果您觉得宽宏大量的话,可以添加一个学分):
私有字符串processCharEscapes(字符串strVal){
//循环助手
char[]chrArr=strVal.toCharArray();
StringBuilder strOut=新的StringBuilder(strVal.length());
String strEsc=”“;//转义序列,字符串缓冲区
Character chrBuf=null;//悬空字符缓冲区
//控制标志
布尔inEscape=false;//在转义中?
布尔值cbOctal3=true;//可以是八进制3位
//解析字符
用于(字符c:chrArr){
如果(!inEscape){
//监听转义序列的开始
如果(c=='\\'){
inEscape=true;//输入escape
strEsc=”“;//重置转义缓冲区
chrBuf=null;//重置悬挂字符缓冲区
cbOctal3=true;//重置cbOctal3标志
}否则{
strOut.append(c);//保存到输出
}
}否则{
//确定逃逸终止
如果(strEsc.length()==0){//第一个字符
如果(c>=48&&c51){//c是一个数字[4-7]
cbOctal3=假;
}
strEsc+=c;//保存到缓冲区
}否则{//c是一个字符
//单字符转义(将终止转义循环)
如果(c='n'){
inEscape=假;
strOut.append('\n');
}else如果(c=='t'){
inEscape=假;
strOut.append('\t');
}else如果(c=='b'){
inEscape=假;
strOut.append('\b');
}else如果(c=='r'){
inEscape=假;
strOut.append('\r');
}else如果(c='f'){
inEscape=假;
strOut.append('\f');
}else if(c=='\\'){
inEscape=假;
strOut.append('\\');
}else if(c=='\''){
inEscape=假;
strOut.append('\'');
}else如果(c==“”){
inEscape=假;
strOut.append(“”);
}否则{
//在转义字符“\”之后看到非法字符
System.err.println(ErrorType.SYNTAX\u ERROR,“非法字符转义序列,无法识别的转义:\\\”+c);
}
}
}else如果(strEsc.length()==1){//第二个字符(可能)
如果(c>=48&&c=48&&c 0){
//strEsc是一种合法的1-3位八进制字符代码,可进行转换和添加
追加((char)Integer.parseInt(strEsc,8));
如果(chrBuf!=null){//有一个悬空字符
//检查链式转义序列(例如。\10\10)
如果(chrBuf=='\\'){
inEscape=true;//输入escape
strEsc=”“;//重置转义缓冲区
chrBuf=null;//重置悬挂字符缓冲区
cbOctal3=true;//重置cbOctal3标志
}否则{
strOut.append(chrBuf);
}
}
}
}
}
//检查下线终止的转义序列(特殊情况)
如果(inEscape){
//strEsc是一种合法的1-3位八进制字符代码,可进行转换和添加
追加((char)Integer.parseInt(strEsc,8));
如果(chrBuf!=null){//有一个悬空字符
strOut.append(chrBuf);
}
}
返回strOut.toString();
}
我希望这对您有所帮助。Apache commons方法将完成这项工作。虽然javadoc描述中不清楚,但这些方法处理unicode转义以及“普通”Java字符串转义。您不能只使用String.replace()吗?除了\r\n之外,如果可能的话,我不想手动替换所有可能的\X文本和\uxxx等。我认为这段代码不处理Unicode转义是正确的吗?这对于最初的使用是可以理解的
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();
}