【问题标题】:Using re.sub with capture groups to replace only portion of a match [duplicate]将 re.sub 与捕获组一起使用以仅替换匹配项的一部分 [重复]
【发布时间】:2023-03-07 18:08:01
【问题描述】:

我有一些文字

>>> import re
>>> text = 'wo__RF**81@t=(181,810)'

我想用正则表达式明确地用'' 替换'wo__RF' 部分。这种模式:

>>> pattern = '\A([\w]+)[@+-/*]*'

将匹配并拉出要删除的字符

>>> re.findall(pattern, text)
Out[6]: ['wo__RF']

但使用re.sub时包含尾随运算符

>>> re.sub(pattern, '', text)
Out[7]: '81@t=(181,810)'

如何使这个输出看起来像这样?

Out[7]: '**81@t=(181,810)'

----编辑----

将模式修改为:

>>> pattern = '\A([\w]+)[@+-/*]*'

产生相同的输出

Out[7]: '81@t=(181,810)'

---- 编辑 2 ----

删除捕获组

>>> pattern = '\A[\w]+[@+/*-]*'
>>> re.sub(pattern, '', text)
Out[11]: '81@t=(181,810)'

【问题讨论】:

  • 其实[@+-/*]必须写成[@+/*-],因为-正在创建一个范围。但是,\w+ 匹配 wo__RF[@+/*-]* 将匹配 **。从字符类中删除*re.sub(r'^\w+[@+/-]*', '', text)?见this regex demo
  • 您对要保留的部分使用捕获组,而不是要删除的部分。
  • 如果顶部评论中的解决方案对您不起作用,请说明您需要删除的具体内容以及原因。
  • @WiktorStribiżew 是的,当然 - 这不是我问题的答案,但以后可能会回来咬我。谢谢。
  • @WiktorStribiżew re.sub() 替换的东西与re.findall 返回的东西不同,这似乎很奇怪。

标签: python regex


【解决方案1】:

使用lookahead 匹配部分字符串而不替换它。

pattern = r'\A\w+(?=[@+\-/*])'

仅删除匹配项时不需要捕获组;如果您需要将部分输入文本复制到结果中,则需要它。在\w 附近也不需要[]。而且你应该去掉[@+\-/*]之后的*,因为你想要其中一个字符。

在创建正则表达式时,您通常应该使用原始字符串,这样就不会将正则表达式转义序列与 Python 转义序列混淆。并且你应该在一个字符集中转义-,否则它被用来创建一个字符范围。

【讨论】:

  • 不要在字符类中使用-,这是不好的做法。使用[@+/*-][-@+/*]
  • 我相信大多数正则表达式引擎都允许你逃避它,你不必使用旧方法将它放在一个特殊的地方。
  • 您将无法在 C++ std::regex 中使用它(我不记得这里的编译器是否有任何区别),也无法在任何 POSIX 正则表达式(如 sed 等)中使用。大多数都没有意思是,这就是为什么我说最佳实践是在字符类的开头或结尾使用它。
  • 我不希望 C++ 使用 Python 答案。
猜你喜欢
  • 2012-08-15
  • 2011-02-15
  • 2015-12-18
  • 2014-06-26
  • 2019-12-14
相关资源
最近更新 更多