【问题标题】:what group does backreference refers to when used with sub() operation?与 sub() 操作一起使用时,反向引用指的是哪个组?
【发布时间】:2014-07-28 11:12:15
【问题描述】:

以下代码:

>>> text = "imagine a new *world*, a *magic* world"
>>> pattern = re.compile(r'\*(.*?)\*')
>>> pattern.sub(r"<b>\1<\b>", text)

输出:

imagine a new <b>world<\x08>, a <\b>magic<\x08> world

我这里有两个问题,

1.) 我不明白为什么反向引用 '\1' 会更改文本的 magic 部分? 我读到'\1' 指的是被捕获的第一组。

2.) 为什么 &lt;\b&gt; 输出 &lt;\x08&gt; 即使在使用 'r' 作为前缀之后。 '\n' 不会发生这种情况。

【问题讨论】:

  • @Bakuriu 是的,但是它应该输出:想象一个新的 world,一个 world 世界,因为 \1 指的是“世界”跨度>

标签: python regex python-2.7 python-3.x regex-group


【解决方案1】:

我去了 IRC,那里的人告诉我,每次使用重复匹配字符串捕获一个组时,bacreference 都会被覆盖。

【讨论】:

    【解决方案2】:
    1. sub 替换 all 匹配项,而不仅仅是第一个匹配项。来自文档:

      返回替换最左边不重叠得到的字符串 替换 repl 在字符串中出现的模式。 [...] 这 可选参数count 是模式出现的最大数量 将被替代; count 必须是非负整数。 如果省略或 零,所有出现的都将被替换。

    2. \b 是一个转义序列(用于退格)。你应该用另一个\ 来逃避它:

      r'<b>\1<\\b>'
      

      用作:

      In [4]: pattern.sub(r'<b>\1<\\b>', text)
      Out[4]: 'imagine a new <b>world<\\b>, a <b>magic<\\b> world'
      

    转义序列在两个不同的时刻被解释:

    • python 编译器在创建字节码时,必须决定将哪些字符放入字符串中。
    • 由re 引擎执行替换时。

    要了解为什么需要双重转义,您可以尝试一次添加一个反斜杠:

    In [18]: print(pattern.sub('<b>\\1<\b>', text))
    imagine a new <b>world>, a <b>magic> world
    
    In [19]: print(pattern.sub('<b>\\1<\\b>', text))
    imagine a new <b>world>, a <b>magic> world
    
    In [20]: print(pattern.sub('<b>\\1<\\\b>', text))
    imagine a new <b>world<>, a <b>magic<> world
    
    In [21]: print(pattern.sub('<b>\\1<\\\\b>', text))
    imagine a new <b>world<\b>, a <b>magic<\b> world
    

    在[18] 中,\b 由 python 编译器解释,因此在字符串中放入了一个真正的退格字符(如您所见,替换它时会删除之前的 &lt; 字符)

    在[19] 中,\\ 被解释为转义的\,但之后,re 引擎发现您要替换包含和转义序列的某些文本并重新解释它,从而产生相同的结果结果为[18]。

    在[20] 中,\\ 被解释为转义的\,最后的\b 被解释为退格。结果是,替换时,退格删除了\。

    在[21] 中,四个\\\\ 被解释为两个转义序列,re 引擎将其解释为单个\,后跟b(预期结果)。使用四个\ 相当于使用原始字符串文字加一个转义。

    【讨论】:

    • @ColdFusion 替换不应该是&lt;/b&gt; 而不是&lt;\b&gt;
    • @CodeFusion 是的,你必须使用both。原始字符串文字 + 转义。问题是在编译时转义首先由解释器解释(并且需要原始字符串文字,以便解释器不会在其中插入反斜杠),然后由re 引擎解释。
    • @hwnd 如果那是 HTML,可能是的,但问题不在于/b,因为它不会产生问题。
    • @hwnd,我知道这似乎很明显,但我想在最后添加 '' 以使其不加粗。
    • @Bakuriu,解释得很好,谢谢,但我仍然感到困惑的一件事是'\n'为什么它打印正常。
    猜你喜欢
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 2017-07-03
    • 2016-10-06
    相关资源
    最近更新 更多