您将如何创建与某个正则表达式匹配的随机字母数字字符串?
这专门用于创建满足常规密码要求的初始密码。
答案 0 :(得分:19)
Welp,只是沉思,但是生成随机输入与正则表达式相匹配的一般问题对于我来说是可行的,因为对于随机的充分放松的定义和对正则表达式的足够紧密的定义。我正在考虑经典的正式定义,它只允许()| *和字母字符。
正则表达式可以映射到名为finite automata的正式机器。这样的机器是有向图,其具有称为最终状态的特定节点,称为初始状态的节点,以及每个边缘上的字母表中的字母。正则表达式接受一个单词,如果它可以从初始状态开始并遍历通过图形标记每个字符的一个边缘并以最终状态结束。
可以构建图形,然后从最终状态开始并向后遍历随机边缘,跟踪路径。在标准结构中,图中的每个节点都可以从初始状态到达,因此您无需担心会出现无法恢复的错误并需要回溯。如果达到初始状态,请停止并读取前进路径。那是你与正则表达式的匹配。
但是,对于何时或是否达到初始状态,没有特别保证。人们必须弄清楚生成的字符串在什么意义上是“随机的”,并且在某种意义上你希望首先从语言中获得一个随机元素。
但是,这可能是思考这个问题的起点!
现在我已经写完了,在我看来,重复解决选择以简化正则表达式模式可能更简单,直到你留下一个简单的字符串。找到模式中的第一个非字母字符。如果是*,则复制前面的项目若干次并删除*。如果是|,则选择要保留的OR项目,然后删除其余项目。对于左边的paren,做同样的事情,但是看看匹配右边的角色后面的角色。如果您首先将正则表达式解析为树表示,这使得paren分组结构更易于使用,这可能更容易。
对于担心决定正则表达式是否真正与任何东西匹配的人来说,等同于停止问题:不,常规语言表现得非常好。您可以判断任何两个正则表达式是否描述了相同的接受字符串集。您基本上是在上面制作机器,然后按照算法生成规范的最小等效机器。对两个正则表达式执行此操作,然后检查生成的最小机器是否相同,这很简单。
答案 1 :(得分:17)
String::Random将从正则表达式的子集生成随机字符串:
#!/usr/bin/perl
use strict;
use warnings;
use String::Random qw/random_regex/;
print random_regex('[A-Za-z]{3}[0-9][A-Z]{2}[!@#$%^&*]'), "\n";
答案 2 :(得分:6)
如果您遇到特定问题,可能会考虑特定的正则表达式。我会采用那个正则表达式,用简单的人类术语解决它的含义,并从那里开始工作。
我怀疑它是可能来创建一个通用的正则表达式随机匹配生成器,但它可能比仅处理特定情况更多 更多的工作 - 即使这种情况发生了变化一年几次。
(实际上,可能无法在最一般意义上生成随机匹配 - 我有一个模糊的记忆,“任何字符串匹配此正则表达式”的问题是伪装的停止问题。顺便说一句,你可能会有更多的运气。)
答案 3 :(得分:3)
我写了Parsley,其中包括Lexer和Generator。
$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[A-Z]{10}[0-9]{2}', 100);
以上示例将生成一个包含100个代码的数组,每个代码前缀为“FOO”,后跟“ABCDEFGHKMNOPRSTUVWXYZ23456789”干草堆中的10个字符和“0123456789”haystack中的2个数字。
答案 4 :(得分:2)
这个PHP库很有前途:ReverseRegex
与所有这些一样,它只处理正则表达式的子集,但它可以执行相当复杂的东西,如英国邮政编码:
([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
答案 5 :(得分:1)
您需要编写一个字符串生成器,它可以解析正则表达式并生成随机长度的随机字符范围成员等。
使用某些规则(以小写字母开头,至少有一个标点符号,大写字母和数字,至少6个字符等)编写随机密码生成器会更容易,然后编写正则表达式以便任何使用上述规则创建的密码有效。
答案 6 :(得分:0)
假设您同时拥有最小长度和4 *(或类似)要求,我只是倾向于使用合适的密码生成器。
我过去构建了一对(基于Web和命令行),并且从来没有跳过多个生成的字符串来传递3-of-4规则。
答案 7 :(得分:0)
有可能(例如,Haskell regexp模块有一个测试套件,可以自动生成应该匹配某些正则表达式的字符串)。
但是,对于手头的简单任务,最好不要使用简单的密码生成器并使用正则表达式过滤其输出。
答案 8 :(得分:0)
使用Generating Random Passwords上接受的答案,直到它与您的正则表达式匹配。
答案 9 :(得分:-1)
为什么不向后工作regexp?一个简单的例子:如果你的正则表达式是
/[a-zA-Z]{6}/
然后你知道你需要6个字母a-z或A-Z,所以要生成它们。当然,这可以变得更加漂亮,并且根据您的需要,您可能最终反向编写整个正则表达式解析器,但是当您满足需要时,您可以停止添加功能。