diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2019-06-25 20:13:39 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2019-06-25 20:13:39 -0400 |
| commit | 65cdd46dce13ca35d73bdf3ebf75789df5581ac9 (patch) | |
| tree | 8fae52d890df565043d890c8cb1b4ed3d389e370 | |
| parent | 942c4e3d28e0eef3efc50160ad3562f7fa1b3695 (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.java | 139 | ||||
| -rw-r--r-- | src/test/java/bjc/everge/StringUtilsTest.java | 33 |
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; } } } |
