diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2018-10-13 15:40:10 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2018-10-13 15:44:22 -0400 |
| commit | bf9737ae3c61c638dca3a40ca847e784ddd750f3 (patch) | |
| tree | d4df8247222c7170c181d00ef6b4400ebe72f323 | |
| parent | 00e1605a7d152fe23ad59e00c2929188814df05c (diff) | |
Pull out levelSplit/levelContains
levelSplit/levelContains from the StringUtils class are now instead in
the new LevelSplitter class in ioutils. This is so that new features of
varying sorts can be added to those functions without cluttering up
StringUtils.
| -rw-r--r-- | base/src/main/java/bjc/utils/funcutils/StringUtils.java | 217 | ||||
| -rw-r--r-- | base/src/main/java/bjc/utils/ioutils/LevelSplitter.java | 260 |
2 files changed, 261 insertions, 216 deletions
diff --git a/base/src/main/java/bjc/utils/funcutils/StringUtils.java b/base/src/main/java/bjc/utils/funcutils/StringUtils.java index 8e75f79..e8558c7 100644 --- a/base/src/main/java/bjc/utils/funcutils/StringUtils.java +++ b/base/src/main/java/bjc/utils/funcutils/StringUtils.java @@ -7,6 +7,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import bjc.utils.data.BooleanToggle; +import bjc.utils.ioutils.LevelSplitter; import bjc.utils.parserutils.TokenUtils; import com.ibm.icu.text.BreakIterator; @@ -254,220 +255,4 @@ public class StringUtils { } return strings; } - - public static boolean levelContains(String haystack, String... needles) { - int nestLevel = 0; - int i = 0; - - boolean prevCharWasSlash = false; - boolean inString = false; - - char stringEnder = ' '; - - while(i < haystack.length()) { - if(inString == false && nestLevel == 0) { - for(String needle : needles) { - if(haystack.regionMatches(i, needle, 0, needle.length())) { - return true; - } - } - } - - if(inString) { - if(prevCharWasSlash == true) { - prevCharWasSlash = false; - } else if (haystack.charAt(i) == stringEnder) { - inString = false; - } - } else { - switch(haystack.charAt(i)) { - case '\'': - inString = true; - stringEnder = '\''; - break; - case '\"': - inString = true; - stringEnder = '\"'; - break; - case '(': - case '[': - case '{': - case '<': - nestLevel += 1; - break; - case ')': - case ']': - case '}': - case '>': - nestLevel = Math.max(0, nestLevel - 1); - break; - } - } - - i += 1; - } - - return false; - } - - public static List<String> levelSplit(String phrase, String... splits) { - return levelSplit(phrase, false, splits); - } - - public static List<String> levelSplit(String phrase, boolean keepDelims, String... splits) { - String work = phrase; - - List<String> strangs = new ArrayList<>(); - - int nestLevel = 0; - int i = 0; - - boolean prevCharWasSlash = false; - boolean inString = false; - - char stringEnder = ' '; - - // Shortcut empty strings - if(phrase.equals("")) { - strangs.add(""); - - return strangs; - } - - while(i < work.length()) { - if(inString == false && nestLevel == 0) { - for(String split : splits) { - if(work.regionMatches(i, split, 0, split.length())) { - strangs.add(work.substring(0, i)); - - if(keepDelims) strangs.add(split); - - work = work.substring(i + split.length()); - i = 0; - - continue; - } - } - } - - if(inString) { - if(prevCharWasSlash == true) { - prevCharWasSlash = false; - } else if (work.charAt(i) == stringEnder) { - inString = false; - } - } else { - /* - * @TODO Ben Culkin 9/4/18 - * - * This currently crashes if the string ends - * with one of the delimiters in question. - */ - switch(work.charAt(i)) { - case '\'': - inString = true; - stringEnder = '\''; - break; - case '\"': - inString = true; - stringEnder = '\"'; - break; - case '(': - case '[': - case '{': - case '<': - nestLevel += 1; - break; - case ')': - case ']': - case '}': - case '>': - nestLevel = Math.max(0, nestLevel - 1); - break; - } - } - - i += 1; - } - - strangs.add(work); - - return strangs; - } - - public static List<String> levelSplitRX(String phrase, String patt) { - return levelSplit(phrase, false, patt); - } - - // @TODO @FIXME - // - // This doesn't seem like its working - public static List<String> levelSplitRX(String phrase, boolean keepDelims, String patt) { - Pattern pat = Pattern.compile(patt); - - String work = phrase; - Matcher mat = pat.matcher(work); - - List<String> strangs = new ArrayList<>(); - - int nestLevel = 0; - int i = 0; - - boolean prevCharWasSlash = false; - boolean inString = false; - - char stringEnder = ' '; - - while(i < work.length()) { - if(inString == false && nestLevel == 0) { - if(mat.find(i)) { - strangs.add(work.substring(0, i)); - if(keepDelims) strangs.add(mat.group()); - work = work.substring(mat.end()); - i = 0; - - mat = pat.matcher(work); - - continue; - } - } - - if(inString) { - if(prevCharWasSlash == true) { - prevCharWasSlash = false; - } else if (work.charAt(i) == stringEnder) { - inString = false; - } - } else { - switch(work.charAt(i)) { - case '\'': - inString = true; - stringEnder = '\''; - break; - case '\"': - inString = true; - stringEnder = '\"'; - break; - case '(': - case '[': - case '{': - case '<': - nestLevel += 1; - break; - case ')': - case ']': - case '}': - case '>': - nestLevel = Math.max(0, nestLevel - 1); - break; - } - } - - i += 1; - } - - strangs.add(work); - - return strangs; - } } diff --git a/base/src/main/java/bjc/utils/ioutils/LevelSplitter.java b/base/src/main/java/bjc/utils/ioutils/LevelSplitter.java new file mode 100644 index 0000000..7de0e28 --- /dev/null +++ b/base/src/main/java/bjc/utils/ioutils/LevelSplitter.java @@ -0,0 +1,260 @@ +package bjc.utils.ioutils; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Splits a string on a delimiter, respecting grouping delimiters. + * + * By default, grouping delimiters are (), [], {}, and <>, as well as single and + * double quoted strings. + * + * @author bjculkin + * + */ +public class LevelSplitter { + /** + * Defaultly configured level splitter. + */ + public final static LevelSplitter def = new LevelSplitter(); + + /** + * Check if a string contains any one of a specified number of things, + * respecting groups. + * + * @param haystack + * The string to look in. + * @param needles + * The strings to look for. + * @return Whether or not any of the strings were contained outside of + * groups. + */ + public boolean levelContains(String haystack, String... needles) { + int nestLevel = 0; + int i = 0; + + boolean prevCharWasSlash = false; + boolean inString = false; + + char stringEnder = ' '; + + while (i < haystack.length()) { + if (inString == false && nestLevel == 0) { + for (String needle : needles) { + if (haystack.regionMatches(i, needle, 0, needle.length())) { + return true; + } + } + } + + if (inString) { + if (prevCharWasSlash == true) { + prevCharWasSlash = false; + } else if (haystack.charAt(i) == stringEnder) { + inString = false; + } + } else { + switch (haystack.charAt(i)) { + case '\'': + inString = true; + stringEnder = '\''; + break; + case '\"': + inString = true; + stringEnder = '\"'; + break; + case '(': + case '[': + case '{': + case '<': + nestLevel += 1; + break; + case ')': + case ']': + case '}': + case '>': + nestLevel = Math.max(0, nestLevel - 1); + break; + } + } + + i += 1; + } + + return false; + } + + /** + * Split a string, respecting groups. + * + * @param phrase + * The string to split. + * @param keepDelims + * Whether or not to include the delimiters in the + * results. + * @param splits + * The strings to split on. + * @return A list of split strings. If keepDelims is true, it also + * includes the delimiters in between the split strings. + */ + public List<String> levelSplit(String phrase, boolean keepDelims, String... splits) { + String work = phrase; + + List<String> strangs = new ArrayList<>(); + + int nestLevel = 0; + int i = 0; + + boolean prevCharWasSlash = false; + boolean inString = false; + + char stringEnder = ' '; + + // Shortcut empty strings + if (phrase.equals("")) { + strangs.add(""); + + return strangs; + } + + while (i < work.length()) { + if (inString == false && nestLevel == 0) { + for (String split : splits) { + if (work.regionMatches(i, split, 0, split.length())) { + strangs.add(work.substring(0, i)); + + if (keepDelims) strangs.add(split); + + work = work.substring(i + split.length()); + i = 0; + + continue; + } + } + } + + if (inString) { + if (prevCharWasSlash == true) { + prevCharWasSlash = false; + } else if (work.charAt(i) == stringEnder) { + inString = false; + } + } else { + /* + * @TODO Ben Culkin 9/4/18 + * + * This currently crashes if the string ends + * with one of the delimiters in question. + */ + switch (work.charAt(i)) { + case '\'': + inString = true; + stringEnder = '\''; + break; + case '\"': + inString = true; + stringEnder = '\"'; + break; + case '(': + case '[': + case '{': + case '<': + nestLevel += 1; + break; + case ')': + case ']': + case '}': + case '>': + nestLevel = Math.max(0, nestLevel - 1); + break; + } + } + + i += 1; + } + + strangs.add(work); + + return strangs; + } + + // @TODO @FIXME + // + // This doesn't seem like its working + @SuppressWarnings("javadoc") + public List<String> levelSplitRX(String phrase, String patt) { + return levelSplit(phrase, false, patt); + } + + @SuppressWarnings("javadoc") + public List<String> levelSplitRX(String phrase, boolean keepDelims, String patt) { + Pattern pat = Pattern.compile(patt); + + String work = phrase; + Matcher mat = pat.matcher(work); + + List<String> strangs = new ArrayList<>(); + + int nestLevel = 0; + int i = 0; + + boolean prevCharWasSlash = false; + boolean inString = false; + + char stringEnder = ' '; + + while (i < work.length()) { + if (inString == false && nestLevel == 0) { + if (mat.find(i)) { + strangs.add(work.substring(0, i)); + if (keepDelims) strangs.add(mat.group()); + work = work.substring(mat.end()); + i = 0; + + mat = pat.matcher(work); + + continue; + } + } + + if (inString) { + if (prevCharWasSlash == true) { + prevCharWasSlash = false; + } else if (work.charAt(i) == stringEnder) { + inString = false; + } + } else { + switch (work.charAt(i)) { + case '\'': + inString = true; + stringEnder = '\''; + break; + case '\"': + inString = true; + stringEnder = '\"'; + break; + case '(': + case '[': + case '{': + case '<': + nestLevel += 1; + break; + case ')': + case ']': + case '}': + case '>': + nestLevel = Math.max(0, nestLevel - 1); + break; + } + } + + i += 1; + } + + strangs.add(work); + + return strangs; + } +} |
