【问题标题】:Is there a way to undo recursive regex operations?有没有办法撤消递归正则表达式操作?
【发布时间】:2023-03-27 09:29:01
【问题描述】:

如果存在进行递归替换的正则表达式操作,例如:

>>> import re
>>> pattern = re.compile(r'[?!]')
>>> s = 'what the?!'
>>> print(pattern.sub(r' \g<0> ', s))
what the ?  !

有没有办法撤消递归操作?

我有这个但是没用:

>>> import re
>>> pattern = re.compile(r'[?!]')
>>> s2 = pattern.sub(r' \g<0> ', s)
>>> s2
'what the ?  ! '
>>> pattern2 = re.compile(r'\s[?!]\s')
>>> s3 = pattern2.sub(r'\g<0>', s2)
>>> s3
'what the ?  ! '
>>> pattern2 = re.compile(r' [?!] ')
>>> s3 = pattern2.sub(r'\g<0>', s2)
>>> s3
'what the ?  ! '

【问题讨论】:

  • Regex101 解释得最好 =) regex101.com/r/WMP7zC/1
  • 你编译pattern2,然后用pattern子编译?
  • 在您的 regex101 链接中,您显示 \g&lt;0&gt; 在搜索模式中递归子模式,但您在替换模式中使用它(它只是一个文字反向引用)。您还混合了 PCRE 和 python 模式。
  • 这里没有递归,顺便说一句。在 Python 中,\g&lt;N&gt; 是一种明确的替换反向引用语法。它不是 PCRE/Oniguruma 子例程调用语法。你应该重新考虑标题。实际上,由于在进行初始替换的位置没有标记,因此无法“撤消”正则表达式替换。但是,下面的解决方案应该适用于这种情况。只需使用r' ([?!]) ' 模式并替换为'\1'

标签: python regex string recursion substitution


【解决方案1】:

您必须将您的角色类包裹在括号中以创建group。然后在替换过程中,您可以将 整个 匹配项(包括空格)替换为仅 (没有空格)。

>>> import re
>>> s2 = 'what the ?  ! '
>>> pattern2 = re.compile(r'\s([?!])\s')  # capture the punctuation part as group 1
>>> s3 = pattern2.sub(r'\g<1>', s2)       # replace the matches with the captured group 1
>>> s3
'what the?!'

【讨论】:

  • 有趣!您能否解释一下为什么在进行初始正则表达式替换时,没有使用该组?
  • @alvas 您在初始替换中使用了零组。零组总是指 whole 匹配(想象你的正则表达式被括号隐式包围)。在您的初始替换中,整个匹配只是标点符号;在您的反向尝试中,整个匹配还包括周围的空间。
  • 当引用一个ID大于0的组时,你甚至不需要\g&lt;N&gt;符号,使用.sub(r'\1', s2)。此外,如果 ?! 被常规空格包围,则“撤消”的模式也应该包含常规空格,而不是通用的 \s 空白类。
猜你喜欢
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2019-06-28
  • 2019-02-11
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
  • 2021-03-19
相关资源
最近更新 更多