How do I generate all possible numbers from this regular expression?
This is not quite a regex-based problem, but from an algorithmic perspective you can do the followings:
- Count the number of
W
's in your string. - Based on the number of
W
's, create the product ofrange(0,9)
, for example if you have 2W
you need to create the products of two[0...9]
lists that will be something like0,0-0,1-0,2-...-9,9
. - Loop over the combinations and replace them with a simple string formatting. For instance when you are iterating over a triple combination suppose with 3 variables
i,j,k
you want want to replace them in a string like7W0W3W
, you can do"7%d0%dW%d"%(i,j,k)
.
And if you are looking for a general regex to wrap all the cases you can use a regex like (w)
(w
in a capture group) then you need to first access to position of the match groups and replace them with combination items (i,j,k,..
).
It's better to call the input string as "pattern", not "regular expression". Also it's probably better to create a "virtual" list which generates the strings on demand. Here's the sample implementation:
public static List<String> getNumbers(String pattern) {
final char[] chars = pattern.toCharArray();
int size = 1;
for(char ch : chars)
if(ch == 'W') {
if(size == 1_000_000_000)
throw new IllegalArgumentException("Too many 'W' to fit the list");
size*=10;
}
final int finalSize = size;
return new AbstractList<String>() {
@Override
public String get(int index) {
char[] res = chars.clone();
for(int i=res.length-1; i>=0; i--) {
if(res[i] == 'W') {
res[i] = (char) ('0'+(index % 10));
index/=10;
}
}
return new String(res);
}
@Override
public int size() {
return finalSize;
}
};
}
First we count the number of 'W'
chars and calculate the target list size accordingly. Then we return an implementation of AbstractList
which for given list index replaces the 'W'
symbols with the remainders of index division by 10
. This list does not take the memory, it generates the String
only when you request it. If you want to get the hard-copy of such list, you can use new ArrayList<>(getNumbers(pattern))
.