将捕获的组恢复为python正则表达式的最佳方法是什么?

时间:2014-06-21 00:10:12

标签: python regex django

鉴于r' a(\ w +)regex'这样的正则表达式,我知道我可以捕获该组,但是如果给定一个捕获的组,我想将其转回到正则表达式中。我已经在下面包含了为实现此目的而构建的功能,但由于我不是正则表达式的专家,我想知道是否有更标准的实现此类行为,或者是什么"最佳实践"将会。

def reverse_capture(regex_string, args, kwargs):
    regex_string = str(regex_string)
    if not args and not kwargs :
        raise ValueError("at least one of args or kwargs must be empty in reverse_capture")
    if kwargs :
        for kwarg in kwargs :
            regex_string = re.sub(r'(?:[^\\[]|[^\\](?:\\\\)+|[^\\](?:\\\\)*\\\[)\(\?P<.+>.+(?:[^\\[]|[^\\](?:\\\\)+|[^\\](?:\\\\)*\\\[)\)',
                                  kwarg,
                                  regex_string)
    elif args :
        for arg in args :
            regex_string = re.sub(r'(?:[^\\[]|[^\\](?:\\\\)+|[^\\](?:\\\\)*\\\[)\(.+(?:[^\\[]|[^\\](?:\\\\)+|[^\\](?:\\\\)*\\\[)\)',
                                  arg,
                                  regex_string)
    else :
        return regex_string

注意:上述功能还没有真正奏效,因为我在尝试覆盖每个案例之前都会想到,我应该在这个网站上提问。

修改

我想我应该澄清一下我的意思。我的目标是编写一个python函数,给出像r&#34; ab(。+)c&#34;这样的正则表达式。和#34;有些strinG&#34;,我们可以得到以下结论:

>>> def reverse_capture(r"ab(.+)c", "Some strinG")
"abSome strinGc"

也就是说,该参数将被替换为捕获组所在的正则表达式。肯定有更好的格式化字符串的方法;但是,正则表达式是在我的用例中给出的,所以这不是一个选项。

对于任何一个好奇的人,我想要做的是创建一个Django包,它将使用模板标签来查找与某个视图函数或命名url相关联的正则表达式,可选择输入一些参数,然后检查模板中的URL是否与标记生成的URL匹配。这将解决一些导航问题。有一个更简单的包,它做了类似的事情,但它并没有为我的用例服务。

示例:

如果reverse_capture是我尝试编写的函数,那么这里有一些输入/输出的例子(我将正则表达式作为原始字符串传递),以及函数调用:

reverse_capture:正则表达式字符串 - &gt;正则表达式 输入:正则表达式和字符串 输出:通过替换参数,字符串的正则表达式的第一个捕获组获得的正则表达式。

的示例:

>>> reverse_capture(r'(.+)', 'TEST')
'TEST'
>>> reverse_capture(r'a longer (.+) regex', 'TEST')
'a longer TEST regex'
>>> reverse_capture(r'regex with two (.+) capture groups(.+)', 'TEST')
'regex with two TEST capture groups(.+)'

2 个答案:

答案 0 :(得分:3)

解析正则表达式可能有点复杂。而不是试图解析正则表达式以找出你需要替换匹配的地方,为什么不从格式字符串构建正则表达式,方便的地方是将字符串格式化为匹配?

这是一个示例模板:

>>> regex_template = r'{} lives at {} Baker Street.'

我们插入捕获组来构建正则表达式:

>>> import re
>>> word_group = r'(\w+)'
>>> digit_group = r'(\d+)'
>>> regex = regex_template.format(word_group, digit_group)

将其与字符串匹配:

>>> groups = re.match(regex, 'Alfred lives at 325 Baker Street.').groups()
>>> groups
('Alfred', '325')

将匹配格式化为字符串格式:

>>> regex_template.format(*groups)
'Alfred lives at 325 Baker Street.'

答案 1 :(得分:0)

对于将来遇到这个问题的人来说,在我搜索之后,似乎没有很好的库函数可以将值替换为正则表达式的捕获组。

解决此问题/编写自己的函数的最简单方法是制作DFA(Deterministic Finite Automaton),这不是很难。

如果您决定使用正则表达式解决它,那么您可以使用answers to this question将DFA转换为正则表达式,这就是我最终实现自己的解决方案的方法。