Skip to content

Instantly share code, notes, and snippets.

@AndersDJohnson
Last active June 5, 2019 13:36
Show Gist options
  • Save AndersDJohnson/c81a62266457bb307e29 to your computer and use it in GitHub Desktop.
Save AndersDJohnson/c81a62266457bb307e29 to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* From http://rosettacode.org/wiki/Brace_expansion#Java
*
* May integrate with https://github.com/AndersDJohnson/brace-expansion-java.
*/
public class BraceExpansion {
public static List<String> expand(String s) {
return expandR("", s, "", new ArrayList<String>());
}
private static List<String> expandR(String pre, String s, String suf, List<String> list) {
int i1 = -1, i2 = 0;
String noEscape = s.replaceAll("([\\\\]{2}|[\\\\][,}{])", " ");
StringBuilder sb = null;
outer:
while ((i1 = noEscape.indexOf('{', i1 + 1)) != -1) {
i2 = i1 + 1;
sb = new StringBuilder(s);
System.out.println("s=" + s);
for (int depth = 1; i2 < s.length() && depth > 0; i2++) {
char c = noEscape.charAt(i2);
Character c2 = null;
int i3 = i2 + 1;
try {
c2 = noEscape.charAt(i3);
}
catch (IndexOutOfBoundsException e) {}
depth = (c == '{') ? ++depth : depth;
depth = (c == '}') ? --depth : depth;
if (c == ',' && depth == 1) {
sb.setCharAt(i2, '\u0000');
}
else if (c == '}' && depth == 0 && sb.indexOf("\u0000") != -1)
break outer;
}
}
if (i1 == -1) {
if (suf.length() > 0)
expandR(pre + s, suf, "", list);
else {
list.add(pre + s + suf);
}
} else {
for (String m : sb.substring(i1 + 1, i2).split("(?:\u0000|\u3040)", -1)) {
System.out.println("m=" + m);
expandR(pre + s.substring(0, i1), m, s.substring(i2 + 1) + suf, list);
}
}
return ranges(list);
}
private static List<String> ranges(List<String> list) {
List<String> newList = new ArrayList<String>();
Pattern p = Pattern.compile("\\{(\\d+)\\.\\.(\\d+)\\}");
for (String st : list) {
Matcher m = p.matcher(st);
boolean found = false;
while (m.find()) {
found = true;
Integer l = Integer.parseInt(m.group(1));
Integer r = Integer.parseInt(m.group(2));
for (; l <= r; ++l) {
newList.add(st.substring(0, m.start()) + l.toString() + st.substring(m.end()));
}
newList = ranges(newList);
}
if (! found) {
newList.add(st);
}
}
return newList;
}
public static void testRanges() {
expand("a{0..1}b{1..9}c");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment