使用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/
)重复这一点似乎对我来说是不必要的。是否有更简洁的方法将字符串与给定数字(不是任意数量)的斜杠进行匹配?
答案 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/'>
通过这种方式,我可以轻松地调整代码以获得任意数量斜杠的模式。