具有特定数字的特定字符的字符串的正则表达式

时间:2017-07-10 16:03:51

标签: python regex scrapy

使用Scrapy选择器(https://doc.scrapy.org/en/latest/topics/selectors.html#regular-expressions),我正在尝试选择具有href属性的网页元素,该属性具有特定数量的正斜杠,例如/foo//foo/bar/(也始终以/开头和结尾。)

到目前为止,为了匹配/foo/bar/之类的相对网址,我想出了

In [24]: re.match('^/[^/]+/[^/]+/$', '/foo/bar/')
Out[24]: <_sre.SRE_Match object; span=(0, 9), match='/foo/bar/'>

然而,对于越来越多的斜杠(例如/foo/bar/bam/)重复这一点似乎对我来说是不必要的。是否有更简洁的方法将字符串与给定数字(不是任意数量)的斜杠进行匹配?

4 个答案:

答案 0 :(得分:3)

您可以使用此正则表达式匹配由/分隔的任意数量的子目录:

^(?:/[^/]+)*[^/]+/?$
  • ^ - 开始
  • (?:/[^/]+)*匹配0个或更多/后跟一个或多个non-/字符串
  • [^/]+匹配路径的最后一个组件
  • /?$最后匹配选项/

答案 1 :(得分:1)

要获取html正文中的网址,最好使用LinkExtractors

from scrapy.linkextractors import LinkExtractor
...
le =  LinkExtractor(allow='^/(?:[^/]+/){2}[^/]+/$') # for links with 2 slashes
all_links = le.extract_links(response) # all links matching the `allow` regex.
...

您还可以在LinkExtractor中包含规则以实际匹配更好的链接。

答案 2 :(得分:1)

我比正则表达式的'其他人'慢得多。您确实指出要检查特定数量的斜杠。这似乎是这样做的。

>>> import re
>>> link = '/foo/bar/foo/bar/foo/bar/foo/bar/'
>>> n=5
>>> re.match(r'(?:/[^/]+){%s}/'%(n-1), link)
<_sre.SRE_Match object; span=(0, 17), match='/foo/bar/foo/bar/'>
>>> n=6
>>> re.match(r'(?:/[^/]+){%s}/'%(n-1), link)
<_sre.SRE_Match object; span=(0, 21), match='/foo/bar/foo/bar/foo/'>

答案 3 :(得分:0)

根据anubhava的回答,我使用{}使用了具有特定数字的非捕获组:

In [33]: re.match('^/(?:[^/]+/){1}[^/]+/$', '/foo/bar/')
Out[33]: <_sre.SRE_Match object; span=(0, 9), match='/foo/bar/'>

In [34]: re.match('^/(?:[^/]+/){2}[^/]+/$', '/foo/bar/bam/')
Out[34]: <_sre.SRE_Match object; span=(0, 13), match='/foo/bar/bam/'>

通过这种方式,我可以轻松地调整代码以获得任意数量斜杠的模式。