README.md in regexp-examples-1.3.2 vs README.md in regexp-examples-1.4.0
- old
+ new
@@ -8,13 +8,12 @@
`Regexp#examples` generates a list of all\* strings that will match the given regular expression.
`Regexp#random_example` returns one, random string (from all possible strings!!) that matches the regex.
-\* If the regex has an infinite number of possible srings that match it, such as `/a*b+c{2,}/`,
+\* If the regex has an infinite number of possible strings that match it, such as `/a*b+c{2,}/`,
or a huge number of possible matches, such as `/.\w/`, then only a subset of these will be listed.
-
For more detail on this, see [configuration options](#configuration-options).
If you'd like to understand how/why this gem works, please check out my [blog post](https://tom-lord.github.io/Reverse-Engineering-Regular-Expressions/) about it.
## Usage
@@ -110,25 +109,25 @@
* ...even for the more "obscure" syntax, e.g. `/(?<future>the) \k'future'/`, `/(a)(b) \k<-1>/`
* ...and even if nested or optional, e.g. `/(even(this(works?))) \1 \2 \3/`, `/what about (this)? \1/`
* Non-capture groups, e.g. `/(?:foo)/`
* Comment groups, e.g. `/foo(?#comment)bar/`
* Control characters, e.g. `/\ca/`, `/\cZ/`, `/\C-9/`
-* Escape sequences, e.g. `/\x42/`, `/\x5word/`, `/#{"\x80".force\_encoding("ASCII-8BIT")}/`
+* Escape sequences, e.g. `/\x42/`, `/\x5word/`, `/#{"\x80".force_encoding("ASCII-8BIT")}/`
* Unicode characters, e.g. `/\u0123/`, `/\uabcd/`, `/\u{789}/`
* Octal characters, e.g. `/\10/`, `/\177/`
* Named properties, e.g. `/\p{L}/` ("Letter"), `/\p{Arabic}/` ("Arabic character")
-, `/\p{^Ll}/` ("Not a lowercase letter"), `/\P{^Canadian\_Aboriginal}/` ("Not not a Canadian aboriginal character")
+, `/\p{^Ll}/` ("Not a lowercase letter"), `/\P{^Canadian_Aboriginal}/` ("Not not a Canadian aboriginal character")
* ...Even between different ruby versions!! (e.g. `/\p{Arabic}/.examples(max_group_results: 999)` will give you a different answer in ruby v2.1.x and v2.2.x)
* **Arbitrarily complex combinations of all the above!**
* Regexp options can also be used:
* Case insensitive examples: `/cool/i.examples #=> ["cool", "cooL", "coOl", "coOL", ...]`
* Multiline examples: `/./m.examples #=> ["\n", "a", "b", "c", "d"]`
* Extended form examples: `/line1 #comment \n line2/x.examples #=> ["line1line2"]`
* Options toggling supported: `/before(?imx-imx)after/`, `/before(?imx-imx:subexpr)after/`
-##Configuration Options
+## Configuration Options
When generating examples, the gem uses 3 configurable values to limit how many examples are listed:
* `max_repeater_variance` (default = `2`) restricts how many examples to return for each repeater. For example:
* `.*` is equivalent to `.{0,2}`
@@ -147,12 +146,14 @@
* `/c+r+a+z+y+ * B+I+G+ * r+e+g+e+x+/i.examples.length <= 10000` -- Attempting this will NOT freeze your system, even though
(by the above rules) this "should" attempt to generate **117546246144** examples.
`Rexexp#examples` makes use of *all* these options; `Rexexp#random_example` only uses `max_repeater_variance`, since the other options are redundant.
-To use an alternative value, simply pass the configuration option as follows:
+### Defining custom configuration values
+To use an alternative value, you can either pass the configuration option as a parameter:
+
```ruby
/a*/.examples(max_repeater_variance: 5)
#=> [''. 'a', 'aa', 'aaa', 'aaaa' 'aaaaa']
/[F-X]/.examples(max_group_results: 10)
#=> ['F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O']
@@ -160,21 +161,43 @@
/[slow]{9}/.examples(max_results_limit: 9999999).length == 4 ** 9 == 262144 # Warning - this will take a while!
/.*/.random_example(max_repeater_variance: 50)
#=> "A very unlikely result!"
```
+Or, set an alternative value *within a block*:
+
+```ruby
+RegexpExamples::Config.with_configuration(max_repeater_variance: 5) do
+ # ...
+end
+```
+
+Or, globally set a different default value:
+
+```ruby
+# e.g In a rails project, you may wish to place this in
+# config/initializers/regexp_examples.rb
+RegexpExamples::Config.max_repeater_variance = 5
+RegexpExamples::Config.max_group_results = 10
+RegexpExamples::Config.max_results_limit = 20000
+```
+
A sensible use case might be, for example, to generate all 1-5 digit strings:
```ruby
/\d{1,5}/.examples(max_repeater_variance: 4, max_group_results: 10, max_results_limit: 100000)
#=> ['0', '1', '2', ..., '99998', '99999']
```
+### Configuration Notes
+
Due to code optimisation, `Regexp#random_example` runs pretty fast even on very complex patterns.
(I.e. It's typically a _lot_ faster than using `/pattern/.examples.sample(1)`.)
For instance, the following takes no more than ~ 1 second on my machine:
`/.*\w+\d{100}/.random_example(max_repeater_variance: 1000)`
+
+All forms of configuration mentioned above **are thread safe**.
## Bugs and TODOs
There are no known major bugs with this library. However, there are a few obscure issues that you *may* encounter: