代码之家  ›  专栏  ›  技术社区  ›  mlissner

在python中生成正则表达式可以匹配的值列表

  •  2
  • mlissner  · 技术社区  · 14 年前

    我试图使用正则表达式作为输入,并从中生成正则表达式将匹配的所有可能值。

    例如,如果regex是“以a开头、以c结尾的三个字母单词”,那么代码将生成一个值为[aac、abc、acc、adc、a1c….]的列表。

    有什么简单的方法可以做到这一点吗?我在用蟒蛇。

    4 回复  |  直到 14 年前
        1
  •  7
  •   Ofri Raviv    14 年前

    这里有一个蛮力解决方案,应该有效。它的运行时间是o(l^max_length)(其中l是字母表的大小),因此使用它的风险自负。

    def all_matching_strings(alphabet, max_length, regex):
    """Find the list of all strings over 'alphabet' of length up to 'max_length' that match 'regex'"""
    
    if max_length == 0: return 
    
    L = len(alphabet)
    for N in range(1, max_length+1):
        indices = [0]*N
        for z in xrange(L**N):
            r = ''.join(alphabet[i] for i in indices)
            if regex.match(r):                
               yield(r)
    
            i = 0
            indices[i] += 1
            while (i<N) and (indices[i]==L):
                indices[i] = 0
                i += 1
                if i<N: indices[i] += 1
    
    return
    

    示例用法:

    alphabet = 'abcdef1234567890'
    import re
    regex = re.compile('f*[1-3]+$')
    for r in all_matching_strings(alphabet, 5, regex): 
        print r
    

    它将输出最长为5的所有字符串,从一个f的序列开始,然后是一个1-3的非空序列,然后结束:

    1
    2
    3
    f1
    11
    21
    31
    f2
    12
    22
    32
    f3
    13
    23
    33
    ff1
    [more output omitted...]
    
        2
  •  4
  •   Ignacio Vazquez-Abrams    14 年前

    你不想这么做。大多数结果集将是巨大的,有些将是无限的。相反,使用一系列测试向量并依次对每个向量应用正则表达式:

    vectors = (
      'foo',
      'bar',
      ...
    )
    
    for result in (re.match(someregex, entry) for entry in vectors):
      ...
    
        3
  •  1
  •   Johannes Charra    14 年前

    当且仅当regexp中有限定符(+或*)时,匹配字符串集是无限的。你的问题似乎不是针对那些模式。我宁愿相信 product 功能来自 itertools 可能会有帮助。

    例如,您可以引入一个表示任意字母的特殊字符(例如下划线),然后构建这样的模式

    patt = 'a_c'
    

    定义你的字母表

    youralphabet = 'abcde...'
    

    定义一个函数,生成所有可能的实例

    def genInstances(patt):
        elems = [c if c != '_' else youralphabet for c in patt]
        return itertools.product(*elems)
    

    然后,您可以通过解析 \d [a-zA-Z] 或者什么。

        4
  •  0
  •   Matt Anderson    14 年前

    一些正则表达式匹配有限数量的输入字符串,但是许多(大多数?)匹配无穷多个输入字符串。这有点像问“给定python语言语法,生成所有可能的python程序”。如果你试过的话,你也许可以写一个程序把它们按顺序列出来(尽管运行起来需要无限的时间),但是你确定你想这样做吗?你为什么要?

    我确信标准库中的正则表达式引擎不会公开生成所需输出的方法。您必须获得对内部数据结构的低级访问权,或者自己实现一些dfa引擎的东西。