【问题标题】:What is the best way to sub captured groups back into a python regex?将捕获的组重新放入 python 正则表达式的最佳方法是什么?
【发布时间】:2014-06-21 00:10:12
【问题描述】:

给定一个像 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"ab(.+)c" 这样的正则表达式和一个像 "Some stringG" 这样的参数,我们可以有以下内容:

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

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

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

示例:

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

reverse_capture : 正则表达式字符串 -> 正则表达式 输入:一个正则表达式和一个字符串 输出:替换参数字符串的第一个捕获组得到的正则表达式。

例子:

>>> 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(.+)'

【问题讨论】:

  • 也许有更好的方法来做到这一点,但在确保整个表达式不在括号中,你找到的括号被转义,他们的转义字符本身没有被转义之间,等等......你可以想象这会变得有点混乱!
  • 做一个更小的例子来做你想做的部分。当你的意图不明确时,让人们看看这种疯狂的逃避很可能会被忽视。
  • 与其尝试解析正则表达式来确定捕获组的位置,为什么不使用字符串格式将文本放置在捕获组需要去的地方?
  • 你到底为什么要这样做呢?您想将结果用作正则表达式,还是只想获取正则表达式匹配的全文?对于匹配对象matchmatch.group() 是匹配的文本。
  • 嗨@user2357112,我添加了一个更新,希望能有所澄清。我确实想将结果用作正则表达式,并且我绝对同意字符串格式更好,但不幸的是,这在这里行不通。我正在尝试做的(在我的编辑中有所描述)本质上是在 Django 平台上使用一种反向 url 查找来拉 url 正则表达式(不是实际的反向 url 查找),将一些参数插入这些正则表达式,然后查看正在呈现模板的 url 是否与新的正则表达式匹配。它与框架的工作方式密切相关。

标签: python regex django


【解决方案1】:

解析正则表达式可能有点复杂。与其尝试解析正则表达式以找出需要替换匹配项的位置,不如从具有方便位置的格式字符串构建正则表达式以对匹配项进行字符串格式化?

这是一个示例模板:

>>> 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.'

【讨论】:

  • 谢谢,我认为这对于大多数用例来说是一个很好的解决方案,但不幸的是我不会构建正则表达式。虽然理论上我可以与我的所有正则表达式并行构建格式字符串,但因为我想将它作为一个包发布,我认为如果我想在正则表达式本身上执行它会节省很多人的时间/代码。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-18
    • 2011-03-31
    • 2012-02-09
    相关资源
    最近更新 更多