summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2019-06-25 20:13:39 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2019-06-25 20:13:39 -0400
commit65cdd46dce13ca35d73bdf3ebf75789df5581ac9 (patch)
tree8fae52d890df565043d890c8cb1b4ed3d389e370
parent942c4e3d28e0eef3efc50160ad3562f7fa1b3695 (diff)
Fix escapeSplit to properly handle chaining escapes
escapeSplit will now properly handle arbitrary length escape sequences and do the right thing.
-rw-r--r--src/main/java/bjc/everge/StringUtils.java139
-rw-r--r--src/test/java/bjc/everge/StringUtilsTest.java33
2 files changed, 148 insertions, 24 deletions
diff --git a/src/main/java/bjc/everge/StringUtils.java b/src/main/java/bjc/everge/StringUtils.java
index 3b40832..f194eae 100644
--- a/src/main/java/bjc/everge/StringUtils.java
+++ b/src/main/java/bjc/everge/StringUtils.java
@@ -20,12 +20,14 @@ public class StringUtils {
* @param escape
* The escape that stops splitting.
* @param splat
- * The string to split on.
+ * The string to split on. If this starts with the escape sequence, things will work
+ * poorly.
* @param inp
* The string to split.
* @return The string split as specified above.
*/
public static String[] escapeSplit(String escape, String splat, String inp) {
+
/*
* Special case some stuffs.
*/
@@ -47,50 +49,141 @@ public class StringUtils {
List<String> ret = new ArrayList<>();
String wrk = inp;
- int idx = wrk.indexOf(splat);
+ int sidx = wrk.indexOf(splat);
+ int eidx = wrk.indexOf(escape);
+
+ boolean hadEscape = false;
+
+ while (sidx != -1 || eidx != -1) {
+ if (eidx > 0 && eidx < sidx) {
+ if (isDebug) System.err.printf("[TRACE] Considering escape\n");
+
+ /*
+ * We potentially have an escaped sequence:
+ * - either an escaped split
+ * - or an escaped escape
+ */
+ // Check for an escaped split
+ if (wrk.regionMatches(eidx + escape.length(), splat, 0, splat.length())) {
+ // Skip over it
+ int ofst = eidx + splat.length();
+
+ // Slice out the escape
+ {
+ String s1 = wrk.substring(0, eidx);
+ String s2 = wrk.substring(eidx + escape.length());
+
+ String s3 = wrk.substring(eidx, eidx + escape.length());
+
+ if (isDebug) {
+ System.err.printf("[TRACE] Skip esc. split (%s)/(%s); (%s)\n",
+ s1, s2, s3);
+ }
+
+ wrk = s1 + s2;
+ }
+
+ sidx = wrk.indexOf(splat, ofst);
+ eidx = wrk.indexOf(escape, ofst);
+
+ if (isDebug) {
+ System.err.printf("[TRACE] After esc. split (%s) %d/%d\n",
+ wrk, sidx, eidx);
+ }
+
+ hadEscape = false;
+ continue;
+ }
- if (isDebug) {
- System.err.printf("[DEBUG] 'hard' escapeSplit: (%s) (%s) (%s) init: %d\n",
- escape, splat, inp, idx);
- }
+ // Check for an escaped escape
+ if (wrk.regionMatches(eidx + escape.length(), escape, 0, escape.length())) {
+ // Skip over it
+ int ofst = eidx + escape.length();
+
+ // Slice out the escape
+ {
+ String s1 = wrk.substring(0, eidx);
+ String s2 = wrk.substring(eidx + escape.length());
+
+ String s3 = wrk.substring(eidx, eidx + escape.length());
+ if (isDebug) {
+ System.err.printf("[TRACE] Skip esc. escape (%s)/(%s); (%s)\n",
+ s1, s2, s3);
+ }
+
+ wrk = s1 + s2;
+ }
+
+ sidx = wrk.indexOf(splat, ofst);
+ eidx = wrk.indexOf(escape, ofst);
+
+ if (isDebug) {
+ System.err.printf("[TRACE] After esc. escape (%s)/(%s) %d/%d\n",
+ wrk, wrk.substring(ofst), sidx, eidx);
+ }
+
+ hadEscape = true;
+ continue;
+ }
+ }
- while (idx != -1) {
- boolean hasEscape = wrk.regionMatches(idx - 1, escape, 0, escape.length());
+ boolean hasEscape = false;
- while (idx != -1 && hasEscape) {
- int oidx = wrk.indexOf(splat, idx + 1);
+ {
+ boolean tmp = wrk.regionMatches(sidx - escape.length(), escape, 0, escape.length());
+
+ hasEscape = hadEscape ? false : tmp;
+ }
+
+ while (sidx != -1 && hasEscape) {
+ int oidx = wrk.indexOf(splat, sidx + escape.length());
if (isDebug) {
- System.err.printf("[TRACE] idx: %d, oidx: %d\n", idx, oidx);
+ String s1 = wrk.substring(0, sidx);
+ String s2 = wrk.substring(sidx, sidx + escape.length());
+ String s3 = wrk.substring(sidx + escape.length());
}
- idx = oidx;
+ if (oidx == -1) break;
+
+ {
+ String s1 = wrk.substring(0, oidx);
+ String s2 = wrk.substring(oidx + escape.length());
+
+ wrk = s1 + s2;
+ }
- hasEscape = wrk.regionMatches(idx - 1, escape, 0, escape.length());
+ sidx = oidx;
+
+ hasEscape = wrk.regionMatches(sidx - escape.length(), escape, 0, escape.length());
}
-
- if (idx == -1) {
+
+ if (sidx == -1) {
break;
}
+ String tmp = wrk.substring(0, sidx);
+
if (isDebug) {
- System.err.printf("[TRACE] sliced string into (%s) and (%s) at %d\n",
- wrk.substring(0, idx), wrk.substring(idx), idx);
+ System.err.printf("[TRACE] Adding (%s) to returned splits; (%s)\n",
+ tmp, wrk.substring(sidx));
}
- String tmp = wrk.substring(0, idx);
ret.add(tmp);
if (!tmp.equals("") && wrk.endsWith(tmp)) {
wrk = "";
} else {
- wrk = wrk.substring(idx + splat.length());
+ if (wrk.indexOf(splat, sidx) != -1) {
+ wrk = wrk.substring(sidx + splat.length());
+ } else {
+ wrk = wrk.substring(sidx);
+ }
}
- idx = wrk.indexOf(splat);
- }
+ sidx = wrk.indexOf(splat);
+ eidx = wrk.indexOf(escape);
- if (isDebug) {
- System.err.printf("\t[TRACE] Remnant is (%s) for string (%s)\n", wrk, inp);
+ hadEscape = false;
}
if (!wrk.equals("")) ret.add(wrk);
diff --git a/src/test/java/bjc/everge/StringUtilsTest.java b/src/test/java/bjc/everge/StringUtilsTest.java
index 9eac017..b20e074 100644
--- a/src/test/java/bjc/everge/StringUtilsTest.java
+++ b/src/test/java/bjc/everge/StringUtilsTest.java
@@ -25,7 +25,20 @@ public class StringUtilsTest {
@Test
public void testEscapeSplit() {
- assertSplitsTo("a / b/c", "/", " ", "a", "/ ", "b/c");
+ assertSplitsTo("a|/||b/c", "|", "/", "a/|b", "c");
+
+ assertSplitsTo("a||/b", "|", "/", "a|", "b");
+ }
+
+ @Test
+ public void testLongSplit() {
+ assertSplitsTo("a||b||c", " ", "||", "a", "b", "c");
+
+ assertSplitsTo("a&&||b||c", "&&", "||", "a||b", "c");
+
+ assertSplitsTo("a&&&&||b||c", "&&", "||", "a&&", "b", "c");
+
+ assertSplitsTo("a&&&&&&||b||c", "&&", "||", "a&&||b", "c");
}
@Test
@@ -36,9 +49,25 @@ public class StringUtilsTest {
}
private void assertSplitsTo(String inp, String esc, String splat, String... right) {
+ assertSplitsTo(false, inp, esc, splat, right);
+ }
+
+ private void assertSplitsTo(boolean doLog, String inp, String esc, String splat, String... right) {
try {
+ if (doLog) StringUtils.isDebug = true;
+
String[] lst = StringUtils.escapeSplit(esc, splat, inp);
+ if (doLog) {
+ System.err.printf("[TRACE] Returned ");
+
+ for (String str : lst) {
+ System.err.printf("(%s) ", str);
+ }
+
+ System.err.println();
+ }
+
assertArrayEquals(right, lst);
} catch (Exception ex) {
System.err.println("EXCEPTION");
@@ -46,6 +75,8 @@ public class StringUtilsTest {
System.err.println();
assertTrue(false);
+ } finally {
+ if (doLog) StringUtils.isDebug = false;
}
}
}