【问题标题】:How to select correct capture group within regex OR?如何在正则表达式 OR 中选择正确的捕获组?
【发布时间】:2020-12-26 08:29:56
【问题描述】:

假设我得到了一个名字列表(名字+名字)。我想匹配列表中由名字和姓氏包围的所有中间名。现在,在 Python 中,我的正则表达式模式字符串是:

regex_str = "|".join([r"\b%s\s+([A-Za-z]+)\s+%s\b" % (first_name, last_name) for (first_name, last_name) in names])

为简单起见,假设为names = [("John", "Smith"), ("Jane", "Doe")]。然后,我们将有regex_str = "\bJohn\s+([A-Za-z]+)\s+Smith\b|\bJane\s+([A-Za-z]+)\s+Doe\b"

现在要遍历一个字符串并将列表中所有“first last”对的所有“first middle last”名称实例更改为简单的“middle”(例如,“John Jack Smith”应该替换为“Jack”) ,我试过了

re.sub(regex_str, r"\1", input_str)

但这仅适用于列表中的第一个名字 (John Smith)。我很快意识到这是因为如果它实际上与列表中的任何其他名称匹配,则捕获组将具有不同的索引,例如 \2 用于第二个名称。有没有办法让捕获组在仍然使用正则表达式的 OR 匹配器的同时获取相应的中间名?

【问题讨论】:

    标签: python regex regex-group


    【解决方案1】:

    由于您使用的是OR,因此正则表达式将匹配任一
    第一部分,因此是第一组 \1,留下 \2 为空 OR
    第二部分,因此是第二组 \2,留下 \1 为空。
    因此,您可以在代码中使用这两个组来替换,如下所示:

    re.sub(regex_str, r"\1\2", input_str)
    

    【讨论】:

    • 这很好,但是如果我的names 列表有超过 99 个名字会怎样?我认为\99 是它可以得到的最大的。
    • 是的,我知道。这只是一种解决方法。不确定是否有动态方式。
    • 您可以使用\g<number> 来通过99 组。@ 987654331@ 及更高版本不起作用的唯一原因是因为无论出于何种原因,Python 想要\0 和 3 位转义表示八进制格式.. 但它们不允许十六进制和 unicode 转义(除非您使用字符串而不是原始字符串,在这种情况下,您必须使用 \\ 来表示 \ 元字符)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 2019-07-16
    相关资源
    最近更新 更多