summaryrefslogtreecommitdiff
path: root/base/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'base/src/main/java')
-rw-r--r--base/src/main/java/bjc/utils/funcutils/StringUtils.java217
-rw-r--r--base/src/main/java/bjc/utils/ioutils/LevelSplitter.java260
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;
+ }
+}