您如何使用re.sub用字符串替换捕获组的内容?

时间:2019-01-04 20:30:39

标签: python regex

我正在尝试确定如何使用re.sub替换捕获组的内容,但是不幸的是,我的大脑太小,无法理解the API documentation for the re.sub function

到目前为止,我已经成功地使用re.search函数隔离了我想替换的字符串,但是使用re.sub函数的API的过程正确地避开了过去,现在和将来。致命而悲剧性大脑的未来能力。

我可以使用re.search模块选择要替换的字符串:

import re

RE_SELECT_CURSOR = re.compile(r'.*\(.*after:\s*(?:"*)([A-Za-z0-9\+\/\=]+)(?:"*)\s*\).*', flags=re.MULTILINE)

query = """
{{
    users(id: "{}") {{
        things(first: {}, after: null){{
            pageInfo {{
                startCursor endCursor hasNextPage
            }}
            edges {{
                node {{
                    id
                }}
            }}
        }}
    }}
}}
"""

#: Identifying the string that I would like to replace (i.e. the "cursor").
matches = re.search(RE_SELECT_CURSOR, query)
if matches:
    cursor = matches.group(1)
    print(cursor)

但是,一旦我尝试将null替换为hello,我的天赋就显而易见了。

#: Trying to replace the "cursor".
result = re.sub(RE_SELECT_CURSOR, "hello", query)
print(result)

结果如下:

{{
    users(id: "{}") {{
hello
            pageInfo {{
                startCursor endCursor hasNextPage
            }}
            edges {{
                node {{
                    id
                }}
            }}
        }}
    }}
}}

我尝试了其他方法,但没有一个起作用-re.sub的正确用法非常明显,但是,在回顾了数十个示例之后,我的大脑根本没有足够的处理能力明白这一点。

一种这样的方法如下,但这是可笑的错误,我知道我应该为自己的“尝试”感到尴尬。

RE_REPLACE_GROUP = '.*\(.*after:\s*(?:"*)("hello")(?:"*)\s*\).*'
result = re.sub(RE_SELECT_CURSOR, RE_REPLACE_GROUP, query)

另一种方法如下,但这也是可笑的错误。

import re

RE_SELECT_CURSOR = re.compile(r'.*\(.*after:\s*(?:"*)([A-Za-z0-9\+\/\=]+)(?:"*)\s*\).*', flags=re.MULTILINE)

query = """
{{
    organization(id: "{}") {{
        assets(first: {}, after: null){{
            pageInfo {{
                startCursor endCursor hasNextPage
            }}
            edges {{
                node {{
                    id
                }}
            }}
        }}
    }}
}}
"""

#: Identifying the string that I would like to replace (i.e. the "cursor").
matches = re.search(RE_SELECT_CURSOR, query)
if matches:
    cursor = matches.group(1)
    query = query.replace("after: {}".format(cursor), "after: {}".format("hello"))
    print(query)

结果如下:

{{
    organization(id: "{}") {{
        assets(first: {}, after: hello){{
            pageInfo {{
                startCursor endCursor hasNextPage
            }}
            edges {{
                node {{
                    id
                }}
            }}
        }}
    }}
}}

从技术上讲,该结果是正确的,但是不能容忍错误位置中的空格。

如何用null代替hello

1 个答案:

答案 0 :(得分:0)

使用group(1)时,您提取了感兴趣的组,但是使用sub时,匹配项被完全替换为 。并且由于表达式的开始和结尾用于匹配上下文,因此在进行求和时,整个匹配将替换为hello;不只是您感兴趣的组。

一种方法是创建3个组,并在比赛时将组替换为原始组\1\3,并用hello更改中央组,如下所示:

import re

RE_SELECT_CURSOR = re.compile(r'(\(.*after:\s*"*)([A-Za-z0-9\+\/\=]+)("*\s*\))')  # you don't need MULTILINE flag or leading/trailing .* patterns

query = """
{{
    users(id: "{}") {{
        things(first: {}, after: null){{
            pageInfo {{
                startCursor endCursor hasNextPage
            }}
            edges {{
                node {{
                    id
                }}
            }}
        }}
    }}
}}
"""


result = re.sub(RE_SELECT_CURSOR, r"\1hello\3", query)
print(result)

打印:

{{
    users(id: "{}") {{
        things(first: {}, after: hello){{
            pageInfo {{
                startCursor endCursor hasNextPage
            }}
            edges {{
                node {{
                    id
                }}
            }}
        }}
    }}
}}