使用re.match在url模式中提取一个部分

时间:2015-12-13 03:31:03

标签: python regex

在nodejs中,我使用正则表达式提取此网址tenanthttp://myServer:8000/api/running/tenant/sk/services下的子部分。它打印正确,sk

代码是,

var re = /(?:[\w\W]+)\/tenant\/([\w]+?)\/(?:[\w\W]*)/
var results = re.exec('http://myServer:8000/api/running/tenant/sk/services')
console.log(results[1])

我将代码移动到python as,

import re
m = re.match(r"(?:\w\W+)tenant/(\w+)/(?:[\w\W]*)", "http://myServer:8000/api/running/tenant/sk/services")
m.group(1)

抛出AttributeError: 'NoneType' object has no attribute 'group'

为什么它与tenant之后的一个单词匹配?

3 个答案:

答案 0 :(得分:2)

findall / search应该帮助你

的findall

>>> m = re.findall(r"(?:\w\W+)tenant/(\w+)/(?:[\w\W]*)", "http://myServer:8000/api/running/tenant/sk/services")
>>> m
['sk']

搜索

>>> m = re.search(r"(?:\w\W+)tenant/(\w+)/(?:[\w\W]*)", "http://myServer:8000/api/running/tenant/sk/services")
>>> m.group(1)
'sk'

原因匹配失败是因为它尝试在字符串的开头匹配它 re.match documentation

  

re.match(pattern,string,flags = 0)如果是零个或多个字符   字符串的开头匹配正则表达式模式,返回一个   相应的MatchObject实例。如果字符串没有,则返回None   匹配模式;请注意,这与零长度不同   匹配。

     

请注意,即使在MULTILINE模式下,re.match()也仅匹配   字符串的开头而不是每行的开头。

     

如果要在字符串中的任何位置找到匹配项,请改用search()   (另请参阅search()与match())。

答案 1 :(得分:2)

match没有group属性。请尝试使用search -

>>>m = re.search(r"(tenant)/(\w+)/(\w+)", "http://myServer:8000/api/running/tenant/sk/services")
>>>m.group(1)
>>>'tenant'
>>>m.group(2)
>>>'sk'
>>>m.group(3)
>>>'services'
>>>m.groups()
>>>('tenant', 'sk', 'services')

或者尝试re.split返回常规列表 - (?<!\\)/(?!=\\)表示查找/之后或之前没有/并按文件分割文字 -

>>>re.split(r"(?<!\\)/(?!=\\)", "http://myServer:8000/api/running/tenant/sk/services")
>>>['http:', '', 'myServer:8000', 'api', 'running', 'tenant', 'sk', 'services']

答案 2 :(得分:1)

实际上,在这种情况下你不需要正则表达式,str.split()就足够了:

>>> url = 'http://myServer:8000/api/running/tenant/sk/services'
>>> l = url.split('/')
>>> l[l.index('tenant')+1]
'sk'
>>>