python匹配正则表达式

时间:2013-09-17 15:56:31

标签: python regex match mask

我需要将主题与正则表达式进行比较,并将匹配掩码与重合键相关联

key_mask = 'foo/{one}/bar/{two}/hello/{world}'

regex_mask = 'foo/(.*)/bar/(.*)/hello/(.*)'

subject = 'foo/test/bar/something/xxx'

回报应该是:

{
"one": "test",
"two": "something",
"world": "xxx"
}

使用3个输入完成此结果的最佳方法是什么?

(这是一个简单的网址路由过滤,如symfony http://symfony.com/doc/current/book/routing.html

谢谢!

2 个答案:

答案 0 :(得分:3)

最简单的想法是在正则表达式中使用命名组:

>>> regex_mask = 'foo/(?P<one>.*)/bar/(?P<two>.*)/hello/(?P<world>.*)'
>>> subject = 'foo/test/bar/something/hello/xxx'
>>> re.match(regex_mask, subject).groupdict()
{'world': 'xxx', 'two': 'something', 'one': 'test'}

答案 1 :(得分:2)

最简单的方法是使用命名组,即使用(.*)而不是普通(?P<name>.*),然后使用groupdict()对象的Match方法。 / p>

但是,如果您无法更改问题的输入(因为您是从其他库中获取它们或其他原因),您可以使用key_maskre.sub自动创建命名组正则表达式并使用简单的函数repl

import re

def to_named_group(match):
    return '(?P<{}>.*)'.format(re.escape(match.group(0)[1:-1]))

def make_regex(key_mask):
    return re.compile(re.sub(r'\{[^}]+\}', to_named_group, key_mask))

def find_matches(key_mask, text):
    return make_regex(key_mask).match(text).groupdict()

用作:

In [10]: find_matches('foo/{one}/bar/{two}/hello/{world}', 'foo/test/bar/something/hello/xxx')
Out[10]: {'one': 'test', 'two': 'something', 'world': 'xxx'}

根据您的评论进行更新:

很容易将有关正则表达式的to_named_group进一步传递给import re from functools import partial def to_named_groups(match, regexes): group_name = re.escape(match.group(0)[1:-1]) group_regex = regexes.get(group_name, '.*') return '(?P<{}>{})'.format(group_name, group_regex) def make_regex(key_mask, regexes): regex = re.sub(r'\{[^}]+\}', partial(to_named_groups, regexes=regexes), key_mask) return re.compile(regex) def find_matches(key_mask, text, regexes=None): if regexes is None: regexes = {} try: return make_regex(key_mask, regexes).search(text).groupdict() except AttributeError: return None 。 例如,您可以将代码更改为:

{{1}}

通过这种方式,您可以控制每个命名组应该匹配的内容。