Packages

A library to generate random strings that match the given Regex

Current section

Files

Jump to
randex lib randex.ex
Raw

lib/randex.ex

defmodule Randex do
@moduledoc """
Randex is a regex based random string generator.
## Example
```elixir
iex(1)> Randex.stream(~r/(1[0-2]|0[1-9])(:[0-5]\d){2} (A|P)M/) |> Enum.take(10)
["10:53:29 AM", "02:54:11 AM", "09:23:04 AM", "10:41:57 AM", "11:42:13 AM",
"10:27:37 AM", "06:15:18 AM", "03:09:58 AM", "09:15:06 AM", "04:25:28 AM"]
```
## Unsupported Features
* [Atomic Grouping and Possessive
Quantifiers](http://erlang.org/doc/man/re.html#sect15)
* [Recursive Patterns](http://erlang.org/doc/man/re.html#sect20)
* [Conditional Subpatterns](http://erlang.org/doc/man/re.html#sect18)
* [Subpatterns as
Subroutines](http://erlang.org/doc/man/re.html#sect21)
* [Backtracking Control](http://erlang.org/doc/man/re.html#sect23)
"""
alias Randex.Generator.Config
@doc ~S"""
Generates random strings that match the given regex
### Options
* max_repetition: (integer) There is no upper limit for some of the
quantifiers like `+`, `*` etc. This config specifies how the upper
limit should be calculated in these cases. The range is calculated
as `min..(min + max_repetition)`. Defaults to `100`.
* mod: (module) The library comes with 3 different types of
generators. Defaults to `Randex.Generator.Random`
`Randex.Generator.Random` - Generates the string in a random manner.
`Randex.Generator.DFS` - This does a depth first traversal. This could be used to generate all possible strings in a systematic manner.
`Randex.Generator.StreamData` - This is built on top of the `StreamData` generators. It could be used as a generator in property testing. Note: this generator might not work well with complicated lookahead or lookbehind expressions.
"""
@spec stream(Regex.t() | String.t()) :: Enumerable.t()
def stream(regex, options \\ []) do
regex =
cond do
is_binary(regex) -> Regex.compile!(regex)
Regex.regex?(regex) -> regex
true -> raise ArgumentError, "Invalid regex: #{inspect(regex)}"
end
source = Regex.source(regex)
source =
case Regex.opts(regex) do
"" -> source
opts -> "(?#{opts})#{source}"
end
config = Map.merge(%Config{}, Enum.into(options, %{}))
Randex.Parser.parse(source)
|> Randex.Generator.gen(config)
end
end