Last active
June 5, 2019 13:36
-
-
Save AndersDJohnson/c81a62266457bb307e29 to your computer and use it in GitHub Desktop.
Brace expansion, alternative to https://github.com/AndersDJohnson/brace-expansion-java.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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