From 5cb4fe1d8ff3547b1f9ca68f97dec9b18ee90e3a Mon Sep 17 00:00:00 2001 From: DQinYuan <932087612@qq.com> Date: Sun, 24 Dec 2023 21:12:08 +0800 Subject: [PATCH 1/2] string support escape --- .../com/ql/util/express/parse/WordSplit.java | 66 ++++++++++++------- .../ql/util/express/bugfix/StringTest.java | 19 ++++++ 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/ql/util/express/parse/WordSplit.java b/src/main/java/com/ql/util/express/parse/WordSplit.java index 631ab61aa..37fe6208b 100644 --- a/src/main/java/com/ql/util/express/parse/WordSplit.java +++ b/src/main/java/com/ql/util/express/parse/WordSplit.java @@ -13,6 +13,12 @@ * @author xuannan */ public class WordSplit { + enum EscapeState { + CHARS, + MAYBE_ESCAPE, + END + } + private WordSplit() { throw new IllegalStateException("Utility class"); } @@ -39,34 +45,46 @@ 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; + 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))) { //小数点的特殊处理 diff --git a/src/test/java/com/ql/util/express/bugfix/StringTest.java b/src/test/java/com/ql/util/express/bugfix/StringTest.java index c8fda9a16..eb4893a25 100644 --- a/src/test/java/com/ql/util/express/bugfix/StringTest.java +++ b/src/test/java/com/ql/util/express/bugfix/StringTest.java @@ -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. */ @@ -18,4 +20,21 @@ public void testFunction() throws Exception { Object result = runner.execute(exp, context, null, false, false); System.out.println(result); } + + @Test + public void stringEscapeTest() throws Exception { + ExpressRunner runner = new ExpressRunner(false, true); + IExpressContext 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", runner.execute("'\\n\\t'", context, null, false, false)); + assertEquals("\n\tm", runner.execute("'\\n\\t\\m'", context, null, false, false)); + assertEquals("", runner.execute("\"\"", context, null, false, false)); + } } From e5f9c0d3ad6b66feaa23879eebbedadeda7baacc Mon Sep 17 00:00:00 2001 From: DQinYuan <932087612@qq.com> Date: Sun, 7 Jan 2024 21:47:00 +0800 Subject: [PATCH 2/2] support '\r' escape --- src/main/java/com/ql/util/express/parse/WordSplit.java | 3 +++ src/test/java/com/ql/util/express/bugfix/StringTest.java | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/ql/util/express/parse/WordSplit.java b/src/main/java/com/ql/util/express/parse/WordSplit.java index 37fe6208b..252fb2937 100644 --- a/src/main/java/com/ql/util/express/parse/WordSplit.java +++ b/src/main/java/com/ql/util/express/parse/WordSplit.java @@ -73,6 +73,9 @@ public static Word[] parse(String[] splitWord, String str) throws Exception { case 't': escapedStr.append('\t'); break; + case 'r': + escapedStr.append('\r'); + break; default: escapedStr.append(curChar); } diff --git a/src/test/java/com/ql/util/express/bugfix/StringTest.java b/src/test/java/com/ql/util/express/bugfix/StringTest.java index eb4893a25..a6f7211ce 100644 --- a/src/test/java/com/ql/util/express/bugfix/StringTest.java +++ b/src/test/java/com/ql/util/express/bugfix/StringTest.java @@ -15,10 +15,9 @@ 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 context = new DefaultContext<>(); Object result = runner.execute(exp, context, null, false, false); - System.out.println(result); + assertArrayEquals(new String[] {"11111", "2222"}, (String[]) result); } @Test @@ -33,8 +32,8 @@ public void stringEscapeTest() throws Exception { // 不认识的转义符 \a, 默认忽略掉 \ assertEquals("aaaaa", runner.execute("'aaa\\aa'", context, null, false, false)); assertEquals("", runner.execute("''", context, null, false, false)); - assertEquals("\n\t", runner.execute("'\\n\\t'", context, null, false, false)); - assertEquals("\n\tm", runner.execute("'\\n\\t\\m'", 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)); } }