python中匹配正则表达式的随机数据生成器

python中匹配正则表达式的随机数据生成器,python,regex,random,Python,Regex,Random,在python中,我正在寻找可以用来创建与任何正则表达式匹配的随机数据的python代码。例如,如果正则表达式是 \d{1,100} 我想要一个随机数列表,随机长度在1到100之间(平均分布) 有一些“regex反相器”可以计算所有可能的匹配,这不是我想要的,而且非常不可行。例如,上面的示例有超过10^100个可能的匹配项,它们永远不能存储在列表中。我只需要一个函数来随机返回匹配 也许已经有一个包可以用来实现这一点?我需要一个函数,它可以为任何正则表达式创建匹配字符串,不仅仅是给定的一个或其他

在python中,我正在寻找可以用来创建与任何正则表达式匹配的随机数据的python代码。例如,如果正则表达式是

\d{1,100}
我想要一个随机数列表,随机长度在1到100之间(平均分布)

有一些“regex反相器”可以计算所有可能的匹配,这不是我想要的,而且非常不可行。例如,上面的示例有超过10^100个可能的匹配项,它们永远不能存储在列表中。我只需要一个函数来随机返回匹配

也许已经有一个包可以用来实现这一点?我需要一个函数,它可以为任何正则表达式创建匹配字符串,不仅仅是给定的一个或其他正则表达式,还可以创建100个不同的正则表达式。我只是无法自己编写代码,我希望函数提取模式以返回匹配字符串。

由此

您可以尝试使用python调用此perl模块:


如果您匹配的表达式没有任何“高级”功能,例如,那么您可以自己解析它并构建适当的生成器

将正则表达式的每个部分视为返回某些内容(例如,在1到100位之间)的函数,并将它们粘在顶部:

import random
from string import digits, uppercase, letters

def joiner(*items):
    # actually should return lambda as the other functions
    return ''.join(item() for item in items)  

def roll(item, n1, n2=None):
    n2 = n2 or n1
    return lambda: ''.join(item() for _ in xrange(random.randint(n1, n2)))

def rand(collection):
    return lambda: random.choice(collection)

# this is a generator for /\d{1,10}:[A-Z]{5}/
print joiner(roll(rand(digits), 1, 10),
             rand(':'),
             roll(rand(uppercase), 5))

# [A-C]{2}\d{2,20}@\w{10,1000}
print joiner(roll(rand('ABC'), 2),
             roll(rand(digits), 2, 20),
             rand('@'),
             roll(rand(letters), 10, 1000))

解析正则表达式将是另一个问题。所以这个解决方案不是通用的,但也许它足够了两个Python库可以做到这一点:sre yield和假说

  • sre产量
  • sre-yeld将生成与给定正则表达式匹配的所有值。它使用SRE,Python的默认正则表达式引擎

    比如说,

    import sre_yield
    list(sre_yield.AllStrings('[a-z]oo$'))
    ['aoo', 'boo', 'coo', 'doo', 'eoo', 'foo', 'goo', 'hoo', 'ioo', 'joo', 'koo', 'loo', 'moo', 'noo', 'ooo', 'poo', 'qoo', 'roo', 'soo', 'too', 'uoo', 'voo', 'woo', 'xoo', 'yoo', 'zoo']
    
    对于十进制数

    list(sre_yield.AllStrings('\d{1,2}'))
    ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99']
    
  • 假设
  • 单元测试库假设将生成随机匹配示例。它也使用SRE构建

    import hypothesis
    g=hypothesis.strategies.from_regex(r'^[A-Z][a-z]$')
    g.example()
    
    输出如下:

    'Gssov', 'Lmsud', 'Ixnoy'
    
    十进制数

    d=hypothesis.strategies.from_regex(r'^[0-9]{1,2}$')
    
    将输出一位或两位十进制数字:65、7、67,但分布不均匀。使用\d生成了无法打印的字符串


    注意:使用开始和结束锚定来防止无关字符。

    \d{1100}
    真正的例子吗?你能粘贴一些你在现实中使用的东西吗?如果正则表达式不太模糊,您可以生成接近匹配表达式的随机字符串,如果不匹配,则丢弃它。给出的示例是“a”示例。我还不知道我到底需要什么。它可以更为复杂,如
    [A-C]{2}\d{2,20}\w{101000}
    。您希望对可能的字符串进行何种分布?例如,对于您的示例,您是否希望大多数随机结果的长度为100位(因为90%的有效匹配字符串都有这么多)?或者你想让每一个长度出现的机会均等吗?后者。每个长度出现的几率应该相等。好吧,你不可能对所有合法的正则表达式模式都解决这个问题,因为任何可以匹配无限长字符串的东西(比如
    \d*
    )都有无限多的可能长度可供选择。但是,如果您将regex语法限制在允许的范围内,这可能是可行的。我更喜欢纯python的解决方案,因为perl解决方案需要(I)修复字符串/随机导入的问题(ii)将参数传递给perl函数(iii)返回输出(iv)可能还有其他关于在不同的机器上运行这段代码的问题,Linux和Windows。这与我在自己的回答中要说的非常接近。是的,这是可以做到的,但仅仅解析正则表达式模式就足够了,我认为这是一个挑战,所以回答者不会随机产生工作代码。@Blckknght:解析正则表达式很困难,但绝对可行,你可以使用正则表达式:)