【问题标题】:Generate random string from regex character set从正则表达式字符集中生成随机字符串
【发布时间】:2013-07-08 19:31:43
【问题描述】:

我认为有一些漂亮的 Pythonic 方式可以做到这一点,但我还没有完全弄清楚。基本上我正在寻找创建一个测试模块,并希望用户能够以一种简单的方式来定义要从中提取的字符集。我可以潜在地连接与字符串相关的各种字符集的列表,但这让我觉得这是一个非常不干净的解决方案。有什么办法可以得到正则表达式所代表的字符集?

例子:

def foo(regex_set):
    re.something(re.compile(regex_set))

foo("[a-z]")
>>> abcdefghijklmnopqrstuvwxyz

编译当然是可选的,但在我看来,这就是这个函数的样子。

【问题讨论】:

  • 是否保证正则表达式匹配一个代码点,或者您想要覆盖正则表达式指定语言中所有符号的最小字母表?
  • 我很确定你不能这样做......至少不干净......如果它只有一个字符,你可以暴力破解它,但那太恶心了为什么不直接使用string.ascii_lowercase
  • 您需要创建自己的解析器,并且您可能只想支持正则表达式语法的一个子集。我认为[a-z](?<![a-hj-z]) 不是您想要支持的东西。 (这是[i] 的一种混淆方式,以防您不认识语法。)
  • 然后创建您自己的语法:az 表示“a 到 z”。 aa 表示“只是一个”。这在任何语言中都不难做到。
  • @SlaterTyranus 有一个字母列表,每个字母旁边都有一个复选框。简单、流行、有据可查的功能。

标签: python regex string


【解决方案1】:

Pyparsing 的作者 Paul McGuire 写了一个 inverse regex parser,你可以用它来做到这一点:

import invRegex
print(''.join(invRegex.invert('[a-z]')))
# abcdefghijklmnopqrstuvwxyz

如果你不想安装 Pyparsing,还有 a regex inverter that uses only modules from the standard library 可以写:

import inverse_regex
print(''.join(inverse_regex.ipermute('[a-z]')))
# abcdefghijklmnopqrstuvwxyz

注意:两个模块都不能反转所有正则表达式模式。


而且这两个模块有区别:

import invRegex
import inverse_regex
print(repr(''.join(invRegex.invert('.'))))
print(repr(''.join(inverse_regex.ipermute('.'))))

产量

'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

这里还有一个区别,这次 pyparsing 枚举了更大的匹配集:

x = list(invRegex.invert('[a-z][0-9]?.'))
y = list(inverse_regex.ipermute('[a-z][0-9]?.'))
print(len(x))
# 26884
print(len(y))
# 1100

【讨论】:

  • 哦,看起来很有前途。让我检查一下。
  • invert(".") 提供了什么?只是出于好奇
  • @JoranBeasley:我已经为两个模块添加了结果。
  • 谢谢......这基本上突出了他想要采取的方法的一些问题......
  • @JoranBeasley - 自己试试看:utilitymill.com/utility/Regex_inverter/13
【解决方案2】:

这里不需要正则表达式。如果你想让用户选择一个字符集,让他们只选择字符。正如我在评论中所说,只需列出所有字符并在它们旁边放置复选框就足够了。如果您想要更紧凑或看起来更酷的东西,您可以执行以下操作之一:

当然,如果你真的使用它,你想出的东西无疑会比这些看起来更好(而且它们实际上也会包含所有字母,而不仅仅是“A”)。

如果需要,您可以包含一个按钮来反转选择、全选、清除选择、保存选择或其他任何您需要做的事情。

【讨论】:

  • 哇,我以为你在开玩笑。赞成概念证明,但我不相信 GUI。
  • 其实我是,但后来我意识到这实际上也是一个很好的解决方案。
  • 对某些人来说当然很棒,因此得到了支持,但您正在与使用 dwm 的人交谈。
  • 实际上,我也不太相信 GUI。不过,有些人似乎喜欢它们。
【解决方案3】:

如果它只是简单的范围,你可以手动解析它

def range_parse(rng):
    min,max = rng.split("-")
    return "".join(chr(i) for i in range(ord(min),ord(max)+1))

print range_parse("a-z")+range_parse('A-Z')

但它的恶心......

【讨论】:

  • 不认为这只是简单的范围。
【解决方案4】:

我想到的另一个简化问题的解决方案:

将您自己的[] 作为提示的一部分粘贴在该行上,并在输入中禁止这些字符。扫描输入并验证它不包含任何匹配 [\[\]] 的内容后,您可以在字符串前面加上 [ 并将 ] 附加到字符串中,并像正则表达式一样使用它来处理所需的所有字符的字符串 (@987654326 @,堡垒实例)。

【讨论】:

    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 2021-10-04
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    相关资源
    最近更新 更多