Skip to content

Commit

Permalink
Merge pull request #38 from curious-odd-man/#36.GenerateNotMatchingSt…
Browse files Browse the repository at this point in the history
…ring

#36 Generate not matching string
  • Loading branch information
curious-odd-man authored Aug 25, 2020
2 parents 9253ba7 + c919518 commit 22b0962
Show file tree
Hide file tree
Showing 38 changed files with 965 additions and 419 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Idea related directories and files
.idea
target/
*.iml
*.iml
src/test/java/com/github/curiousoddman/rgxgen/CustomTests.java
46 changes: 31 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@ Build status:

Follow the link to Online IDE with already created simple project: [JDoodle](https://www.jdoodle.com/a/1NCw)

Note: 1.0 version is imported there - unfortunately currently I can't change it to latest (1.1).

Luckly there is no big difference between 1.0 and 1.1
> Note: 1.0 version is there.
Enter your pattern and see the results.


## Usage

### Maven dependency
Expand Down Expand Up @@ -56,24 +53,36 @@ Enter your pattern and see the results.

Changes:

- Fixed: Top level alternatives without group now working properly: https://github.com/curious-odd-man/RgxGen/issues/31
- Fixed: Top level alternatives without group now working properly: [#31](https://github.com/curious-odd-man/RgxGen/issues/31)
- Fixed: Empty alternatives not always work: [#35](https://github.com/curious-odd-man/RgxGen/issues/35)
- Feature: Now it is possible to generate strings that does not match a pattern (see usage below) [#36](https://github.com/curious-odd-man/RgxGen/issues/36)


### Code:
```java
RgxGen rgxGen = new RgxGen("[^0-9]*[12]?[0-9]{1,2}[^0-9]*"); // Create generator
String s = rgxGen.generate(); // Generate new random value
BigInteger estimation = rgxGen.numUnique(); // The estimation (not accurate, see Limitations) how much unique values can be generated with that pattern.
StringIterator uniqueStrings = rgxGen.iterateUnique(); // Iterate over unique values (not accurate, see Limitations)
public class Main {
public static void main(String[] args){
RgxGen rgxGen = new RgxGen("[^0-9]*[12]?[0-9]{1,2}[^0-9]*"); // Create generator
String s = rgxGen.generate(); // Generate new random value
BigInteger estimation = rgxGen.numUnique(); // The estimation (not accurate, see Limitations) how much unique values can be generated with that pattern.
StringIterator uniqueStrings = rgxGen.iterateUnique(); // Iterate over unique values (not accurate, see Limitations)
String notMatching = rgxGen.generateNotMatching(); // Generate not matching string
}
}
```

```java
RgxGen rgxGen = new RgxGen("[^0-9]*[12]?[0-9]{1,2}[^0-9]*"); // Create generator
Random rnd = new Random(1234)
String s = rgxGen.generate(rnd); // Generate first value
String s1 = rgxGen.generate(rnd); // Generate second value
String s2 = rgxGen.generate(rnd); // Generate third value
// On each launch s, s1 and s2 will be the same
public class Main {
public static void main(String[] args){
RgxGen rgxGen = new RgxGen("[^0-9]*[12]?[0-9]{1,2}[^0-9]*"); // Create generator
Random rnd = new Random(1234)
String s = rgxGen.generate(rnd); // Generate first value
String s1 = rgxGen.generate(rnd); // Generate second value
String s2 = rgxGen.generate(rnd); // Generate third value
String notMatching = rgxGen.generateNotMatching(rnd); // Generate not matching string
// On each launch s, s1 and s2 will be the same
}
}
```

## Supported syntax
Expand Down Expand Up @@ -131,6 +140,13 @@ On the contrast, when generating **unique values** - the number of maximum repet
Use `a{n,m}` if you require some specific number of repetitions.
It is suggested to avoid using such infinite patterns to generate data based on regex.

### Not matching values generation

The general rule is - I am trying to generate not matching strings of same length as would be matching strings, though it is not always possible.
For example pattern `.` - any symbol - would yield empty string as not matching string.
Another example `a{0,2}` - this pattern could yield empty string, but for not matching string the resulting strings would be only 1 or 2 symbols long.
I chose these approaches because they seem predictible and easier to implement.

## Other tools to generate values by regex and why this might be better

There are 2 more libraries available to achieve same goal:
Expand Down
27 changes: 0 additions & 27 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
<!-- Dependencies versions -->
<junit.version>4.12</junit.version>
<jmh.version>1.21</jmh.version>
<slf4j.version>1.7.29</slf4j.version>
<log4j.version>2.13.3</log4j.version>

<!-- Plugins versions -->
<compiler.plugin.version>3.8.1</compiler.plugin.version>
Expand Down Expand Up @@ -257,38 +255,13 @@
</build>

<dependencies>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>

<!-- Test scope below -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
Expand Down
30 changes: 26 additions & 4 deletions src/main/java/com/github/curiousoddman/rgxgen/RgxGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.github.curiousoddman.rgxgen.generator.nodes.Node;
import com.github.curiousoddman.rgxgen.generator.visitors.GenerationVisitor;
import com.github.curiousoddman.rgxgen.generator.visitors.NotMatchingGenerationVisitor;
import com.github.curiousoddman.rgxgen.generator.visitors.UniqueGenerationVisitor;
import com.github.curiousoddman.rgxgen.generator.visitors.UniqueValuesCountingVisitor;
import com.github.curiousoddman.rgxgen.iterators.StringIterator;
Expand Down Expand Up @@ -89,16 +90,15 @@ public StringIterator iterateUnique() {
/**
* Generate random string from the pattern.
*
* @return generated string.
* @return matching random string
*/
public String generate() {
GenerationVisitor gv = new GenerationVisitor();
aNode.visit(gv);
return gv.getString();
return generate(new Random());
}

/**
* Generate random string from the pattern.
* Random initialized with same seed will produce same results.
*
* @param random random to use for the generation.
* @return generated string.
Expand All @@ -108,4 +108,26 @@ public String generate(Random random) {
aNode.visit(gv);
return gv.getString();
}

/**
* Generate random string that does not match a pattern.
*
* @return not matching random string.
*/
public String generateNotMatching() {
return generateNotMatching(new Random());
}

/**
* Generate random string that does not match a pattern.
* Random initialized with same seed will produce same results.
*
* @param random random to use for the generation.
* @return generated string.
*/
public String generateNotMatching(Random random) {
NotMatchingGenerationVisitor nmgv = new NotMatchingGenerationVisitor(random);
aNode.visit(nmgv);
return nmgv.getString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,15 @@
/* **************************************************************************/

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class Choice implements Node {

private static final Logger LOGGER = LoggerFactory.getLogger(Choice.class);
public class Choice extends Node {

private final Node[] aNodes;

public Choice(Node... nodes) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Creating from {} ", Arrays.asList(nodes));
}
public Choice(String pattern, Node... nodes) {
super(pattern);
aNodes = nodes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@
/* **************************************************************************/

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FinalSymbol implements Node {

private static final Logger LOGGER = LoggerFactory.getLogger(FinalSymbol.class);

public class FinalSymbol extends Node {
private final String aValue;

public FinalSymbol(String value) {
LOGGER.trace("Creating '{}'", value);
super(value);
aValue = value;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,13 @@
/* **************************************************************************/

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Group implements Node {
private static final Logger LOGGER = LoggerFactory.getLogger(Group.class);

public class Group extends Node {
private final Node aNode;
private final int aGroupIndex;

public Group(int index, Node node) {
LOGGER.trace("Crating idx = '{}' from '{}'", index, node);
public Group(String pattern, int index, Node node) {
super(pattern);
aNode = node;
aGroupIndex = index;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@
/* **************************************************************************/

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GroupRef implements Node {

private static final Logger LOGGER = LoggerFactory.getLogger(GroupRef.class);

public class GroupRef extends Node {
private final int aIndex;

public GroupRef(int index) {
LOGGER.trace("Crating idx = '{}'", index);
public GroupRef(String pattern, int index) {
super(pattern);
aIndex = index;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;

public interface Node {
void visit(NodeVisitor visitor);
public abstract class Node {
private final String aPattern;

protected Node(String pattern) {
aPattern = pattern;
}

public abstract void visit(NodeVisitor visitor);

public String getPattern() {
return aPattern;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,15 @@
/* **************************************************************************/

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Pattern;

public class NotSymbol implements Node {

private static final Logger LOGGER = LoggerFactory.getLogger(NotSymbol.class);

public class NotSymbol extends Node {
private final Pattern aSubPattern;

// TODO: Parse this pattern always!!
public NotSymbol(String pattern) {
LOGGER.trace("Crating '{}'", pattern);
super(pattern);
aSubPattern = Pattern.compile(pattern);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,22 @@
/* **************************************************************************/

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Repeat implements Node {

private static final Logger LOGGER = LoggerFactory.getLogger(Repeat.class);

public class Repeat extends Node {
private final Node aNode;
private final int aMin;
private final int aMax;

public static Repeat minimum(Node node, int times) {
return new Repeat(node, times, -1);
public static Repeat minimum(String pattern, Node node, int times) {
return new Repeat(pattern, node, times, -1);
}

public Repeat(Node node, int times) {
this(node, times, times);
public Repeat(String pattern, Node node, int times) {
this(pattern, node, times, times);
}

public Repeat(Node node, int min, int max) {
LOGGER.trace("Crating ({} to {}) '{}'", min, max, node);
public Repeat(String pattern, Node node, int min, int max) {
super(pattern);
aNode = node;
aMin = min;
aMax = max;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,14 @@
/* **************************************************************************/

import com.github.curiousoddman.rgxgen.generator.visitors.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class Sequence implements Node {

private static final Logger LOGGER = LoggerFactory.getLogger(Sequence.class);

public class Sequence extends Node {
private final Node[] aNodes;

public Sequence(Node... nodes) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Creating from {} ", Arrays.asList(nodes));
}
public Sequence(String pattern, Node... nodes) {
super(pattern);
aNodes = nodes;
}

Expand Down
Loading

0 comments on commit 22b0962

Please sign in to comment.