如何检查一个字符串是否匹配多个模式?

3
我想在定义模式列表中检查一个URL。 我的模式列表如下:
pat = ['/FoodListAdminCP/Login[/]?', '/FoodListAdminCP[/]?']

我使用了这段代码来检查URL是否与此列表中的某一项匹配。
import re
f = re.compile('|'.join(pat))
if f.match(self.request.uri):
    self.login = True
else:
    self.login = False

现在,如果我请求/FoodListAdminCP/Dashboard作为URL,它将与模式匹配。因为此URL的开头与我的列表中的'/FoodListAdminCP[/]?'匹配。

我希望我的请求URL与列表项的整个部分匹配,而不是部分匹配。

我该如何做呢?

3个回答

5
如果你想要将整个URL与你的模式进行匹配,你可以使用'^'和'$'来匹配字符串的开头和结尾。
在你的示例中,你可以使用:
f = re.compile('|'.join( '(^'+p+'$)' for p in pat ))

获取正则表达式

'(^/FoodListAdminCP/Login[/]?$)|(^/FoodListAdminCP[/]?$)'

从您的pat列表中。

3

如果您不想连接模式,因为这可能不够灵活,而是单独匹配它们,您可以使用[re.compile(p).match(uri) for p in pat]列表推导式来获取所有模式的匹配结果列表:

>>> import re

>>> pat = ['/FoodListAdminCP/Login[/]?', '/FoodListAdminCP[/]?']
>>> uri = '/FoodListAdminCP/Dashboard'

>>> match_results = [re.compile(p).match(uri) for p in pat]
>>> match_results
[None, <_sre.SRE_Match object at 0x101c05d30>]

然后您可以使用all来查询所有结果是否都匹配,这正是您所需要的登录

>>> login = all(match_results)
>>> login
False

或者简而言之:

login = all([re.compile(p).match(uri) for p in pat])

1
或者使用生成器表达式,因为 all 会短路。 - Maciej Gol

1

在你的正则表达式末尾加上 \Z。

f = re.compile('(' + '|'.join(pat) + ')\Z')

你可能也想在正则表达式的开头添加一个 '\A',否则像 '/xxxx/FoodListAdminCP/' 这样的字符串也会被匹配到。 - MartinStettner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接