Skip to content

Commit

Permalink
Merge pull request #310 from alibaba/fix_string_escape
Browse files Browse the repository at this point in the history
string support escape
  • Loading branch information
DQinYuan authored Mar 31, 2024
2 parents 8363eb4 + e5f9c0d commit b7f361f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 26 deletions.
69 changes: 45 additions & 24 deletions src/main/java/com/ql/util/express/parse/WordSplit.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
* @author xuannan
*/
public class WordSplit {
enum EscapeState {
CHARS,
MAYBE_ESCAPE,
END
}

private WordSplit() {
throw new IllegalStateException("Utility class");
}
Expand All @@ -39,34 +45,49 @@ public static Word[] parse(String[] splitWord, String str) throws Exception {
c = str.charAt(i);
//字符串处理
if (c == '"' || c == '\'') {
int index = str.indexOf(c, i + 1);
//处理字符串中的”问题
while (index > 0 && str.charAt(index - 1) == '\\') {
index = str.indexOf(c, index + 1);
}
if (index < 0) {
throw new QLCompileException("字符串没有关闭");
}
String tempDealStr = str.substring(i, index + 1);
//处理 \\,\"的情况
StringBuilder tmpResult = new StringBuilder();
int tmpPoint = tempDealStr.indexOf("\\");
while (tmpPoint >= 0) {
tmpResult.append(tempDealStr, 0, tmpPoint);
if (tmpPoint == tempDealStr.length() - 1) {
throw new QLCompileException("字符串中的" + "\\错误:" + tempDealStr);
StringBuilder escapedStr = new StringBuilder().append(c);
EscapeState state = EscapeState.CHARS;
int current = i;

forward:
while (++current < str.length()) {
char curChar = str.charAt(current);
switch (state) {
case CHARS:
if (curChar == '\\') {
state = EscapeState.MAYBE_ESCAPE;
continue;
}
escapedStr.append(curChar);
if (curChar == c) {
state = EscapeState.END;
break forward;
}

break;
case MAYBE_ESCAPE:
switch (curChar) {
case 'n':
escapedStr.append('\n');
break;
case 't':
escapedStr.append('\t');
break;
case 'r':
escapedStr.append('\r');
break;
default:
escapedStr.append(curChar);
}
state = EscapeState.CHARS;
}
tmpResult.append(tempDealStr.charAt(tmpPoint + 1));
tempDealStr = tempDealStr.substring(tmpPoint + 2);
tmpPoint = tempDealStr.indexOf("\\");
}
tmpResult.append(tempDealStr);
list.add(new Word(tmpResult.toString(), line, i - currentLineOffset + 1));

if (point < i) {
list.add(new Word(str.substring(point, i), line, point - currentLineOffset + 1));
if (state != EscapeState.END) {
throw new QLCompileException("字符串没有关闭");
}
i = index + 1;
list.add(new Word(escapedStr.toString(), line, i - currentLineOffset + 1));
i = current + 1;
point = i;
} else if (c == '.' && point < i && isNumber(str.substring(point, i))) {
//小数点的特殊处理
Expand Down
22 changes: 20 additions & 2 deletions src/test/java/com/ql/util/express/bugfix/StringTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.ql.util.express.IExpressContext;
import org.junit.Test;

import static org.junit.Assert.*;

/**
* Created by tianqiao on 17/7/5.
*/
Expand All @@ -13,9 +15,25 @@ public class StringTest {
public void testFunction() throws Exception {
ExpressRunner runner = new ExpressRunner();
String exp = "a = \"11111,2222\";p = a.split(\",\");";
System.out.println(exp);
IExpressContext<String, Object> context = new DefaultContext<>();
Object result = runner.execute(exp, context, null, false, false);
System.out.println(result);
assertArrayEquals(new String[] {"11111", "2222"}, (String[]) result);
}

@Test
public void stringEscapeTest() throws Exception {
ExpressRunner runner = new ExpressRunner(false, true);
IExpressContext<String, Object> context = new DefaultContext<>();

assertEquals("\"aaa\"", runner.execute("\"\\\"aaa\\\"\"", context, null, false, false));
assertEquals("aaa'aa", runner.execute("'aaa\\'aa'", context, null, false, false));
assertEquals("aaa\\aa", runner.execute("'aaa\\\\aa'", context, null, false, false));

// 不认识的转义符 \a, 默认忽略掉 \
assertEquals("aaaaa", runner.execute("'aaa\\aa'", context, null, false, false));
assertEquals("", runner.execute("''", context, null, false, false));
assertEquals("\n\t\r", runner.execute("'\\n\\t\\r'", context, null, false, false));
assertEquals("\n\tm\r", runner.execute("'\\n\\t\\m\\r'", context, null, false, false));
assertEquals("", runner.execute("\"\"", context, null, false, false));
}
}

0 comments on commit b7f361f

Please sign in to comment.