#!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11160313 use warnings; use List::AllUtils qw( sample ); $SIG{__WARN__} = sub { die @_ }; for my $regex ( split /\n/, <<'END' ) \d{3}[-,.][A-V][a-z]{3}\d{2} [a-c]{2}[-,.]\d{3}-[A-Z]{2} abc*de? a?b?c?d?e? (ab?c){3} END { print "\nThe Regex: $regex\n\n"; my $strings = generate_random_strings( $regex, 10 ); print "@$strings\n"; } sub generate_random_strings { my ($regex, $count) = @_; eval { my $tree = parse( $regex ); # print $tree->show, "\n"; # NOTE uncomment to see parse tree return [ map $tree->run, 1 .. $count ]; } or print " $@\n"; } sub CHAR::run { $_[0][0] } sub ONEOF::run { sample 1, @{$_[0]} } sub SEQ::run { join '', map $_->run, $_[0]->@* } sub REPEAT::run { join '', map $_[0][2]->run, 1 .. sample 1, $_[0][0] .. $_[0][1]; } sub CHAR::show { "char @{$_[0]}\n" } sub ONEOF::show { "oneof @{$_[0]}\n" } sub SEQ::show { $_[0][0]->show . $_[0][1]->show } sub REPEAT::show { my ($min, $max, $body) = $_[0]->@*; "repeat from $min to $max times\n" . $body->show =~ s/^/ /gmr } sub node { bless [ @_[1..$#_] ], $_[0] } sub error { die "ERROR: @_ \n" } sub want { /\G$_[1]/gc ? shift : error pop } sub parse { local $_ = shift; my $tree = expr(); pos($_) == length or error "incomplete parse"; return $tree; } sub withranges { split //, shift =~ s/(.)-(.)/ join '', map chr, ord($1) .. ord($2) /gesr; } sub expr { my $tree = /\G\\d/gc ? node ONEOF => 0 .. 9 : /\G\\w/gc ? node ONEOF => withranges '0-9A-Za-z_' : /\G\[(.+?)\]/gc ? node ONEOF => withranges $1 : /\G([- !"#\$%&',.\/:;<=>\@^_`~0-9A-Za-z])/gc ? node CHAR => "$1" : /\G\((?:\?:)?/gc ? want expr(), qr/\)/, 'missing right paren' : error 'operand expected'; $tree = /\G\{(\d+)\}/gc ? node REPEAT => "$1", "$1", $tree : /\G\{(\d+),(\d)\}/gc ? node REPEAT => "$1", "$2", $tree : /\G\?/gc ? node REPEAT => 0, 1, $tree : /\G\*/gc ? node REPEAT => 0, 5, $tree : /\G\+/gc ? node REPEAT => 1, 5, $tree : /\G(?=[^)])/gc ? node SEQ => $tree, expr() : return $tree while 1; } #### The Regex: \d{3}[-,.][A-V][a-z]{3}\d{2} 175-Mucn14 959-Qznv29 167.Rrfx39 554-Ibhv74 095.Pcwu22 659-Knno96 438.Qiou66 730.Cirx72 201.Rcmm97 823,Cade99 The Regex: [a-c]{2}[-,.]\d{3}-[A-Z]{2} cc-249-NP ab-910-DK ab,430-GE bb-928-YG cb,283-BN ba.476-RJ cb-026-PC cb-799-FW ba-301-TE bc-159-EP The Regex: abc*de? abcccde abccd abcccde abccccd abcccccd abccde abccccd abccd abd abcccccd The Regex: a?b?c?d?e? d abde ad abc a bcde abd ce de be The Regex: (ab?c){3} abcabcac abcacabc abcabcac acacac acacabc abcacac acacac abcacabc abcacac abcabcac