与正则expression式匹配的随机string
你将如何创build一个匹配特定正则expression式的随机字母数字string?
这是专门用于创build初始密码,以满足正常的密码要求。
Welp只是在思考,但是生成与正则expression式相匹配的随机input的一般问题听起来对于我来说是足够宽松的定义随机和足够严格的正则expression式的定义。 我正在考虑古典正式定义,它只允许()| *和字母字符。
正则expression式可以映射到称为有限自动机的正式机器。 这样的机器是一个有向图,有一个称为最终状态的特定节点,一个称为初始状态的节点,以及每个边上的字母表中的一个字母。 如果可以从初始状态开始,并通过graphics遍历每个字符标记的一个边,并在最终状态结束,则正则expression式接受一个单词。
可以build立graphics,然后从最终状态开始,向后遍历随机边,跟踪path。 在一个标准的构造中,graphics中的每个节点都可以从初始状态到达,所以你不必担心不可修复的错误和需要回溯。 如果你达到初始状态,停下来,读下前进的道路。 这是你的正则expression式的匹配。
不过,关于何时或是否达到初始状态并没有特别的保证。 人们必须弄清楚生成的string是什么意思,是“随机的”,从某种意义上说,你希望首先从语言中随机select一个元素。
虽然也许这是考虑问题的出发点!
现在我已经写出来了,在我看来,重复解决select以简化正则expression式模式可能会更简单,直到您留下一个简单的string。 在模式中find第一个非字母字符。 如果是*,则复制前面的项目几次,然后删除*。 如果是|,select要保存的OR项中的哪一个,然后删除其余项。 对于左paren,做同样的,但看着匹配右paren后面的字符。 如果先将正则expression式parsing为树形表示forms,使paren分组结构更易于使用,这可能会更容易一些。
对于担心决定正则expression式是否匹配任何东西的人来说,相当于暂停的问题:不,正则语言的performance相当好。 您可以判断任何两个正则expression式是否描述了同一组接受的string。 你基本上使机器在上面,然后按照algorithm生成一个典型的最小等价机。 做两个正则expression式,然后检查最终的最小机器是否相等,这很简单。
在Perl中的String :: Random将从正则expression式的子集中生成一个随机的string:
#!/usr/bin/perl use strict; use warnings; use String::Random qw/random_regex/; print random_regex('[A-Za-z]{3}[0-9][AZ]{2}[!@#$%^&*]'), "\n";
如果你有一个特定的问题,你可能有一个特定的正则expression式。 我会采取正则expression式,用简单的语言来expression它的意思,并从那里开始工作。
我怀疑是否有可能创build一个普通的正则expression式随机匹配生成器,但它可能比处理特定的案例要多得多 ,即使这种情况每年都会改变几次。
(实际上,从最普遍的意义上说,我们可能无法产生随机匹配 – 我有一个模糊的记忆,“任何string匹配这个正则expression式”的问题是变相的停止问题,用一个非常简化的正则expression式语言虽然你可能有更多的运气。)
我写了荷兰芹 ,其中包括一个Lexer和一个发生器。
- Lexer用于将正则expression式string转换为令牌序列。
- 发生器正在使用这些标记来产生定义数量的代码。
$generator = new \Gajus\Parsley\Generator(); /** * Generate a set of random codes based on Parsley pattern. * Codes are guaranteed to be unique within the set. * * @param string $pattern Parsley pattern. * @param int $amount Number of codes to generate. * @param int $safeguard Number of additional codes generated in case there are duplicates that need to be replaced. * @return array */ $codes = $generator->generateFromPattern('FOO[AZ]{10}[0-9]{2}', 100);
上面的例子将生成一个包含100个代码的数组,每个代码的前缀都是“FOO”,随后是来自“ABCDEFGHKMNOPRSTUVWXYZ23456789”干草堆的10个字符和来自“0123456789”干草堆的2个数字。
这个PHP库看起来很有前途: ReverseRegex
像所有这些,它只处理正则expression式的一个子集,但它可以做相当复杂的东西,如英国邮政编码:
([A-PR-UWYZ]([0-9]([0-9]|[A-HJKSTUW])?|[A-HK-Y][0-9]([0-9]|[ABEHMNPRVWXY])?) ?[0-9][ABD-HJLNP-UW-Z]{2}|GIR0AA)
输出
D43WF B6 6SB MP445FR P9 7EX N9 2DH GQ28 4UL NH1 2SL KY2 9LS TE4Y 0AP
您需要编写一个string生成器,可以parsing正则expression式,并为随机长度生成随机字符范围成员等。
编写一个随机的密码生成器(一个小写字母,至less有一个标点符号,大写字母和数字,至less6个字符等),然后写你的正则expression式,以便创build任何密码说规则是有效的。
假设你有一个最小长度和3 * 4 *(或类似)的要求,我只是倾向于使用一个体面的密码生成器。
过去我已经构build了一对(基于web和命令行),并且从来没有必须跳过多于一个生成的string来通过3/4规则。
- 3/4:必须至less具有以下三种特征:小写,大写,数字,符号
这是可能的(例如,Haskell正则expression式模块有一个testing套件,它会自动生成应该匹配某些正则expression式的string)。
然而,对于一个简单的任务你可能会更好的采取一个简单的密码生成器,并过滤它的输出与你的正则expression式。
在生成随机密码中使用接受的答案,直到它匹配您的正则expression式。
为什么不向后运行正则expression式? 一个简单的例子:如果你的正则expression式是
/[a-zA-Z]{6}/
那么你知道你需要6个字母AZ或AZ,所以生成它们。 当然,这可能会更有趣,根据您的需要,最终可能会反编写整个正则expression式parsing器,但是如果您已经满足了需求,则可以停止添加function。