从网址

时间:2016-05-18 21:42:50

标签: python regex

我想从网址中提取UUID。

例如:

  

/帖/ eb8c6d25-8784-4cdf-b016-4d8f6df64a62 mc_cid = 37387dcb5f&安培; mc_eid = 787bbeceb2
  /职位/ d78fa5da-4cbb-43b5-9fae-2b5c86f883cb / UID / 7034
  / posts / 5ff0021c-16cd-4f66-8881-ee28197ed1cf

我有成千上万的这种字符串。

我的正则表达式现在是".*\/posts\/(.*)[/?]+.*" 这给了我这样的结果:

  

d78fa5da-4cbb-43b5-9fae-2b5c86f883cb / UID
  84ba0472-926d-4f50-b3c6-46376b2fe9de / UID
  6f3c97c1-b877-40e0-9479-6bdb826b7b8f / UID
  f5e5dc6a-f42b-47d1-8ab1-6ae533415d24
  f5e5dc6a-f42b-47d1-8ab1-6ae533415d24
  f7842dce-73a3-4984-bbb0-21d7ebce1749
  fdc6c48f-b124-447d-b4fc-bb528abb8e24

正如您所看到的,我的正则表达式无法摆脱​​/uid,但处理?xxxx,查询参数,罚款。

我错过了什么?怎么做对了?

由于

2 个答案:

答案 0 :(得分:3)

对于UUID,.*模式太宽泛而且贪婪

>>> import re
>>> data = """
... /posts/eb8c6d25-8784-4cdf-b016-4d8f6df64a62?mc_cid=37387dcb5f&mc_eid=787bbeceb2
... /posts/d78fa5da-4cbb-43b5-9fae-2b5c86f883cb/uid/7034
... /posts/5ff0021c-16cd-4f66-8881-ee28197ed1cf
... """
>>> 
>>> re.findall(r"/posts/([A-Za-z0-9\-]+)", data)
['eb8c6d25-8784-4cdf-b016-4d8f6df64a62', 
 'd78fa5da-4cbb-43b5-9fae-2b5c86f883cb', 
 '5ff0021c-16cd-4f66-8881-ee28197ed1cf']

或者,您可以对UUID格式更加严格,请参阅更多信息:

答案 1 :(得分:2)

正则表达式尝试匹配尽可能多的字符(非正式地称为" maximal munch")。

您的正则表达式.*\/posts\/(.*)[/?]+.*的简明英语描述类似于:

  

匹配任何内容,然后是/posts/,后跟任何内容,后跟一个或多个/?,后跟任何内容。

当我们将该正则表达式应用于此文本时:

.../posts/d78fa5da-4cbb-43b5-9fae-2b5c86f883cb/uid/7034

...最大的咀嚼规则要求第二个"任何"匹配是尽可能长的,因此它最终匹配超过你想要的:

d78fa5da-4cbb-43b5-9fae-2b5c86f883cb/uid

...因为仍剩下/7034部分,与正则表达式的其余部分相匹配。

解决此问题的最佳方法是使用一个正则表达式,匹配实际出现在UID中的字符(如@alecxe所建议的那样)。