【问题标题】:Python backreference replacing doesn't work as expectedPython 反向引用替换无法按预期工作
【发布时间】:2015-07-12 01:54:11
【问题描述】:

我的模式中有两个命名组:myFlag 和 id,我想在组 之前再添加一个 myFlag id。

这是我当前的代码:

# i'm using Python 3.4.2
import re
import os
contents = b'''
xdlg::xdlg(x_app* pApp, CWnd* pParent)
    : customized_dlg((UINT)0, pParent, pApp)
    , m_pReaderApp(pApp)
    , m_info(pApp)
{

}
'''

pattern = rb'(?P<myFlag>[a-zA-Z0-9_]+)::(?P=myFlag).+:.+(?P<id>\(UINT\)0 *,)'
res = re.search(pattern, contents, re.DOTALL)
if None != res:
    print(res.groups()) # the output is (b'xdlg', b'(UINT)0,')

# 'replPattern' becomes b'(?P<myFlag>[a-zA-Z0-9_]+)::(?P=myFlag).+:.+((?P=myFlag)\\(UINT\\)0 *,)'
replPattern = pattern.replace(b'?P<id>', b'(?P=myFlag)', re.DOTALL)
print(replPattern)
contents = re.sub(pattern, replPattern, contents)
print(contents)

预期的结果应该是:

xdlg::xdlg(x_app* pApp, CWnd* pParent)
    : customized_dlg(xdlg(UINT)0, pParent, pApp)
    , m_pReaderApp(pApp)
    , m_info(pApp)
{

}

但现在结果和原来的一样:

 xdlg::xdlg(x_app* pApp, CWnd* pParent)
    : customized_dlg((UINT)0, pParent, pApp)
    , m_pReaderApp(pApp)
    , m_info(pApp)
{

}

【问题讨论】:

  • 为什么要用(?P=myFlag)(带括号)替换?P&lt;id&gt;(无括号)?
  • 此外,输入中没有第三个xdlg 字符串。您到底想在这里实现什么目标?
  • 因为我想用'myFlag'组替换字符串,所以必须用括号括起来(python语法)
  • 这里的预期输出是什么?你想解决什么问题?
  • 您用反向引用替换了命名组的名称,正则表达式语法在这里没有意义。

标签: python regex replace


【解决方案1】:

问题似乎在于模式语法——尤其是结尾:

0 *,)

这真的没有意义......修复它似乎可以解决大部分问题,尽管我建议放弃DOTALL 并改用MULTILINE:

p = re.compile(ur'([a-zA-Z0-9_]+)::\1(.*\n\W+:.*)(\(UINT\)0,.*)', re.MULTILINE)
sub = u"\\1::\\1\\2\\1\\3"
result = re.sub(p, sub, s)

print(result)

结果:

xdlg::xdlg(x_app* pApp, CWnd* pParent)
    : customized_dlg(xdlg(UINT)0, pParent, pApp)
    , m_pReaderApp(pApp)
    , m_info(pApp)
{

}

https://regex101.com/r/hG3lV7/1

【讨论】:

  • 我试过你的模式,它确实有效。但是,我很困惑,有必要引入5个组吗? 2组可以解决这个问题吗?
  • 没有五个组是不必要的(见编辑),虽然我不能完全理解你的那些。在我看来,Python 中的命名组有点毫无价值,除非你有很多组需要跟踪多个替换等。否则只是更多的代码本质上会使事情变得更加混乱。
  • 没必要,去掉吧。我认为这种模式也可以进一步改进——在这种情况下,答案主要是为了说明问题所在。
  • 如何使用 re.DOTALL 达到同样的效果?
  • re.DOTALL 应该与上面的模式一起使用(仍然使用三个捕获组),尽管可以简化为类似于([a-zA-Z0-9_]+)::\1(.*)(\(UINT\)0,.*)。
猜你喜欢
  • 2020-06-15
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
相关资源
最近更新 更多