Using Regex to generate Strings rather than match them
Edit:
Complete list of suggested libraries on this question:
- Xeger* - Java
- Generex* - Java
- Rgxgen - Java
- rxrdg - C#
* - Depends on dk.brics.automaton
Edit: As mentioned in the comments, there is a library available at Google Code to achieve this: https://code.google.com/archive/p/xeger/
See also https://github.com/mifmif/Generex as suggested by Mifmif
Original message:
Firstly, with a complex enough regexp, I believe this can be impossible. But you should be able to put something together for simple regexps.
If you take a look at the source code of the class java.util.regex.Pattern, you'll see that it uses an internal representation of Node instances. Each of the different pattern components have their own implementation of a Node subclass. These Nodes are organised into a tree.
By producing a visitor that traverses this tree, you should be able to call an overloaded generator method or some kind of Builder that cobbles something together.
It's too late to help the original poster, but it could help a newcomer. Generex is a useful java library that provides many features for using regexes to generate strings (random generation, generating a string based on its index, generating all strings...).
Example :
Generex generex = new Generex("[0-3]([a-c]|[e-g]{1,2})");
// generate the second String in lexicographical order that matches the given Regex.
String secondString = generex.getMatchedString(2);
System.out.println(secondString);// it print '0b'
// Generate all String that matches the given Regex.
List<String> matchedStrs = generex.getAllMatchedStrings();
// Using Generex iterator
Iterator iterator = generex.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
// it prints 0a 0b 0c 0e 0ee 0e 0e 0f 0fe 0f 0f 0g 0ge 0g 0g 1a 1b 1c 1e
// 1ee 1e 1e 1f 1fe 1f 1f 1g 1ge 1g 1g 2a 2b 2c 2e 2ee 2e 2e 2f 2fe 2f 2f 2g
// 2ge 2g 2g 3a 3b 3c 3e 3ee 3e 3e 3f 3fe 3f 3f 3g 3ge 3g 3g 1ee
// Generate random String
String randomStr = generex.random();
System.out.println(randomStr);// a random value from the previous String list
Disclosure
The project mentioned on this post belongs to the user answering (Mifmif) the question. As per the rules, this need to be brought up.
Xeger (Java) is capable of doing it as well:
String regex = "[ab]{4,6}c";
Xeger generator = new Xeger(regex);
String result = generator.generate();
assert result.matches(regex);
This question is really old, though the problem was actual for me.
I've tried xeger and Generex and they doesn't seem to meet my reguirements.
They actually fail to process some of the regex patterns (like a{60000}
) or for others (e.g. (A|B|C|D|E|F)
) they just don't produce all possible values. Since I didn't find any another appropriate solution - I've created my own library.
https://github.com/curious-odd-man/RgxGen
This library can be used to generate both matching and non-matching string.
There is also artifact on maven central available.
Usage example:
RgxGen rgxGen = new RgxGen(aRegex); // Create generator
String s = rgxGen.generate(); // Generate new random value