【问题标题】:Replace specific named group with re.sub in python在python中用re.sub替换特定的命名组
【发布时间】:2016-08-02 01:15:46
【问题描述】:

我创建了一个正则表达式来查找像 /places/:state/:city/whatever 这样的网址

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$')

这很好用:

import re

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$')
path = '/places/NY/NY/other/stuff'
match = p.match(path)
print match.groupdict()

打印{'city': 'NY', 'state': 'NY'}

如何处理日志文件以将/places/NY/NY/other/stuff 替换为字符串"/places/:state/:city/other/stuff"?我想了解有多少网址属于“城市类型”,而不关心这些地方具体是什么(NYNY)。

简单的方法可能会失败:

import re

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$')
path = '/places/NY/NY/other/stuff'
match = p.match(path)
if match:
  groupdict = match.groupdict()
  for k, v in sorted(groupdict.items()):
    path = path.replace(v, ':' + k, 1)
print path

将打印/places/:city/:state/other/stuff,这是向后的!

感觉应该有办法使用re.sub,但我看不到。

【问题讨论】:

  • 你已经对字典进行了排序,所以在替换过程中citystate 之前
  • @MosesKoledoye 是由groupdict() 返回的值,保证按照与匹配项相同的顺序(或任何特定顺序)进行排序?好像只是一个内置的&lt;type 'dict'&gt;
  • 是的,它或多或少是内置的dict。 dict 中项目的顺序不会反映匹配的顺序。
  • 使用 re.findall 您可以按正确的顺序获取捕获,并且在 re.sub 中您可以将文本替换为对捕获部分的反向引用。
  • @WiktorStribiżew 虽然这是真的,但不幸的是它没有给我组名以及匹配项,所以我必须将它与正则表达式本身分开存储。

标签: python regex string-substitution


【解决方案1】:

想出了一个更好的方法来做到这一点。在已编译的正则表达式上有一个属性groupindex,它在模式字符串中打印组及其顺序

>>> p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$')
>>> p.groupindex
{'city': 2, 'state': 1}

这可以很容易地以正确的顺序迭代:

>>> sorted(p.groupindex.items(), key=lambda x: x[1])
[('state', 1), ('city', 2)]

使用这个,我应该能够保证我以正确的从左到右的顺序替换匹配项:

p = re.compile('^/places/(?P<state>[^/]+)/(?P<city>[^/]+).*$')
path = '/places/NY/NY/other/stuff'
match = p.match(path)
if match:
    groupdict = match.groupdict()
    for k, _ in sorted(p.groupindex.items(), key=lambda x: x[1]):
        path = path.replace(groupdict[k], ':' + k, 1)
print path

这会以正确的顺序循环组,从而确保替换也以正确的顺序发生,从而可靠地产生正确的字符串:

/places/:state/:city/other/stuff

【讨论】:

    猜你喜欢
    • 2015-02-22
    • 2020-06-16
    • 2016-10-13
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多