1

我创建了一个正则表达式来查找像/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"?我想了解有多少网址属于“城市类型”,而不关心这些地方具体是 ( NY, NY)。

简单的方法可能会失败:

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但我看不到。

4

1 回答 1

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
于 2016-08-02T18:20:22.557 回答