package arkref.ext.fig.basic;
import java.util.*;
import java.util.regex.*;
import java.lang.reflect.*;
public class StrUtils {
public static String[] split(String s) {
// Differs from Java's functions in that it returns String[0] on ""
return split(s, " ");
}
public static String[] split(String s, String delim) {
return isEmpty(s) ? new String[0] : s.split(delim);
}
// delim is treated as a string, rather than a list of delimiters
public static List<String> splitByStr(String s, String delim) {
if(isEmpty(s)) return Collections.emptyList();
ArrayList<String> tokens = new ArrayList<String>();
int i = 0;
while(i < s.length()) {
int j = s.indexOf(delim, i);
if(j == -1) break;
tokens.add(s.substring(i, j));
i = j + delim.length();
}
tokens.add(s.substring(i));
return tokens;
}
// Return the first occurrence of c that doesn't have an escape character in
// front of it starting at position i
public static int indexOfIgnoreEscaped(String s, char c) {
return indexOfIgnoreEscaped(s, c, 0);
}
public static int indexOfIgnoreEscaped(String s, char c, int i) {
return indexOfIgnoreEscaped(s, ""+c, i);
}
// Find first occurrence of some non-escaped character in cs
public static int indexOfIgnoreEscaped(String s, String cs, int i) {
boolean escape = false;
while(i < s.length()) {
if(escape)
escape = false;
else {
if(s.charAt(i) == '\\') // Enable escaping
escape = true;
else
if(cs.indexOf(s.charAt(i)) != -1) return i;
}
i++;
}
return -1;
}
// Split, but mind the escaped delimiters.
// Example: "a\ b c" => "a\ b" "c"
public static List<String> splitIgnoreEscaped(String line, String delim) {
// Split
String[] tokens = StrUtils.split(line, delim);
// But now, have to piece together the escaped delimiters
List<String> newTokens = new ArrayList<String>();
for(int i = 0; i < tokens.length; i++) {
if(tokens[i].endsWith("\\") && i+1 < tokens.length)
tokens[i+1] = tokens[i].substring(0, tokens[i].length()-1) + "\\" + delim + tokens[i+1];
else
newTokens.add(tokens[i]);
}
return newTokens;
}
public static double[] doubleSplit(String s, String delim) {
String[] tokens = split(s, delim);
double[] data = new double[tokens.length];
for(int i = 0; i < tokens.length; i++)
data[i] = Double.parseDouble(tokens[i]);
return data;
}
public static double[] doubleSplit(String s) { return doubleSplit(s, " "); }
public static int[] intSplit(String s, String delim) {
String[] tokens = split(s, delim);
int[] data = new int[tokens.length];
for(int i = 0; i < tokens.length; i++)
data[i] = Integer.parseInt(tokens[i]);
return data;
}
public static int[] intSplit(String s) { return intSplit(s, " "); }
public static short[] shortSplit(String s, String delim) {
String[] tokens = split(s, delim);
short[] data = new short[tokens.length];
for(int i = 0; i < tokens.length; i++)
data[i] = Short.parseShort(tokens[i]);
return data;
}
public static short[] shortSplit(String s) { return shortSplit(s, " "); }
public static List<Integer> intSplitList(String s, String delim) {
String[] tokens = split(s, delim);
ArrayList<Integer> data = new ArrayList<Integer>(tokens.length);
for(int i = 0; i < tokens.length; i++)
data.add(Integer.parseInt(tokens[i]));
return data;
}
public static List<Integer> intSplitList(String s) {
return intSplitList(s, " ");
}
// Example: a=3 b=4
public static Map<String, String> parseHashMap(String line, String keyValueDelim) {
return parseHashMap(line, keyValueDelim, " ");
}
public static Map<String, String> parseHashMap(String line, String keyValueDelim, String entryDelim) {
return parseHashMap(Arrays.asList(StrUtils.split(line, entryDelim)), keyValueDelim);
}
public static Map<String, String> parseHashMap(List<String> tokens, String keyValueDelim) {
Map<String, String> map = new HashMap<String, String>();
for(String token : tokens) {
String[] kv = token.split(keyValueDelim);
if(kv.length != 2) continue; // Be silent?
map.put(kv[0], kv[1]);
}
return map;
}
public static TDoubleMap<String> parseTDoubleMap(String line, String keyValueDelim) {
return parseTDoubleMap(line, keyValueDelim, " ");
}
public static TDoubleMap<String> parseTDoubleMap(String line, String keyValueDelim, String entryDelim) {
TDoubleMap<String> map = new TDoubleMap<String>();
String[] tokens = line.split(entryDelim);
for(String token : tokens) {
String[] kv = token.split(keyValueDelim);
if(kv.length != 2) continue; // Be silent?
map.put(kv[0], Double.parseDouble(kv[1]));
}
return map;
}
public static <T> String join(double[] list) {
return join(list, " ");
}
public static <T> String join(double[] list, String delim) {
if(list == null) return "";
List<Double> objs = new ArrayList<Double>();
for(double x : list) objs.add(x);
return join(objs, delim);
}
public static String join(int[] list) { return join(list, " "); }
public static String join(int[] list, String delim) {
if(list == null) return "";
List<Integer> objs = new ArrayList<Integer>();
for(int x : list) objs.add(x);
return join(objs, delim);
}
public static String join(boolean[] list) { return join(list, " "); }
public static String join(boolean[] list, String delim) {
if(list == null) return "";
List<Boolean> objs = new ArrayList<Boolean>();
for(boolean x : list) objs.add(x);
return join(objs, delim);
}
public static <T> String join(T[] objs) {
if(objs == null) return "";
return join(Arrays.asList(objs), " ");
}
public static <T> String join(T[] objs, int start, int end) {
if(objs == null) return "";
return join(Arrays.asList(objs), " ", start, end);
}
public static <T> String join(List<T> objs) {
return join(objs, " ");
}
public static <T> String join(T[] objs, String delim) {
if(objs == null) return "";
return join(Arrays.asList(objs), delim);
}
public static <T> String join(List<T> objs, String delim) {
if(objs == null) return "";
return join(objs, delim, 0, objs.size());
}
public static <T> String join(List<T> objs, String delim, int start, int end) {
if(objs == null) return "";
StringBuilder sb = new StringBuilder();
boolean first = true;
for(int i = start; i < end; i++) {
if(!first) sb.append(delim);
sb.append(objs.get(i));
first = false;
}
return sb.toString();
}
public static <T> String join(Collection<T> objs, String delim) {
if(objs == null) return "";
StringBuilder sb = new StringBuilder();
boolean first = true;
for(T x : objs) {
if(!first) sb.append(delim);
sb.append(x);
first = false;
}
return sb.toString();
}
public static String join(int[] x, boolean withIndices, int magnitudeThreshold) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < x.length; i++) {
if(Math.abs(x[i]) < magnitudeThreshold) continue;
if(i > 0) sb.append(' ');
if(withIndices) sb.append(i+":");
sb.append(x[i]);
}
return sb.toString();
}
public static String joinWithIndices(int[] x) { return join(x, true, 0); }
public static String join(double[] x, boolean withIndices, double magnitudeThreshold) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < x.length; i++) {
if(Math.abs(x[i]) < magnitudeThreshold) continue;
if(i > 0) sb.append(' ');
if(withIndices) sb.append(i+":");
sb.append(x[i]);
}
return sb.toString();
}
public static String joinWithIndices(double[] x) { return join(x, true, 0); }
// Format a matrix with spaces and newlines
public static <T> String join(T[][] data, String[] rowNames, String[] colNames) {
int r0 = (colNames == null ? 0 : 1);
int c0 = (rowNames == null ? 0 : 1);
int R = data.length;
int C = data[0].length;
String[][] mat = new String[R+r0][C+r0];
for(int r = 0; r < R; r++)
for(int c = 0; c < C; c++)
mat[r+r0][c+c0] = ""+data[r][c];
if(rowNames != null)
for(int r = 0; r < R; r++)
mat[r+r0][0] = rowNames[r];
if(colNames != null)
for(int c = 0; c < C; c++)
mat[0][c+c0] = colNames[c];
int[] widths = new int[C+c0];
for(int c = 0; c < C+c0; c++) {
for(int r = 0; r < R+r0; r++) {
if(mat[r][c] == null) mat[r][c] = "";
widths[c] = Math.max(widths[c], mat[r][c].length());
}
}
StringBuilder buf = new StringBuilder();
for(int r = 0; r < R+r0; r++) {
for(int c = 0; c < C+c0; c++) {
String fmt = "%-"+(widths[c]+1)+"s";
buf.append(String.format(fmt, mat[r][c]));
}
buf.append("\n");
}
return buf.toString();
}
public static String toString(Object o) {
return o == null ? null : o.toString();
}
public static boolean isEmpty(String s) { return s == null || s.equals(""); }
public static String repeat(String s, int n) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; i++)
sb.append(s);
return sb.toString();
}
// Regular expression
public static Matcher match(String pattern, String s) {
return Pattern.compile(pattern).matcher(s);
}
public static String[] format(String fmt, Object... is) {
int n = Array.getLength(is[0]);
String[] out = new String[n];
for(int i = 0; i < n; i++) {
Object[] args = new Object[is.length];
for(int j = 0; j < is.length; j++)
args[j] = Array.get(is[j], i);
out[i] = String.format(fmt, args);
}
return out;
}
}