我可以从正则表达式创建列表吗?

时间:2015-11-20 13:13:00

标签: python regex

我正在制作一个爬虫。 用户可以指定正则表达式字符串来下载数据。

当用户输入表格为:

http://xxx/abc[x-z]/image(9|10|11).png

我想下载这些。

http://xxx/abcx/image9.png
http://xxx/abcy/image9.png
http://xxx/abcz/image9.png
http://xxx/abcx/image10.png
http://xxx/abcy/image10.png
http://xxx/abcz/image10.png
http://xxx/abcx/image11.png
http://xxx/abcy/image11.png
http://xxx/abcz/image11.png

我可以从上面的正则表达式字符串创建以下列表吗?或者,我可以在for-in块中使用每个字符串吗?

3 个答案:

答案 0 :(得分:6)

如果您想要将用户的正则表达式作为输入并生成字符串列表,您可以使用库sre_yield

然而,要非常清楚,尝试解析每个可能的正则表达式字符串可能会很快失控。您需要确保您的用户了解通配符和开放式或重复组对可能匹配的字符串数量的影响。

例如,您的正则表达式字符串:http://xxx/abc[x-z]/image(9|10|11).png不会转义.,这是任何字符的通配符,因此会生成许多意外的字符串。相反,我们需要转义它,如下例所示:

>>> import sre_yield

>>> links = []

>>> for each in sre_yield.AllStrings(r'http://xxx/abc[x-z]/image(9|10|11)\.png'):
        links.append(each)

或更简单地links = list(sre_yield.AllStrings(r'http://xxx/abc[x-z]/image(9|10|11)\.png'))

结果是:

>>> links

['http://xxx/abcx/image9.png', 'http://xxx/abcy/image9.png', 
'http://xxx/abcz/image9.png', 'http://xxx/abcx/image10.png', 
'http://xxx/abcy/image10.png', 'http://xxx/abcz/image10.png', 
'http://xxx/abcx/image11.png', 'http://xxx/abcy/image11.png', 
'http://xxx/abcz/image11.png']

答案 1 :(得分:1)

您可以使用product()内置版中的itertools

from itertools import product

for x, y in product(['x', 'y', 'z'], range(9, 12)):
    print 'http://xxx/abc{}/image{}'.format(x, y)

要构建列表,您可以使用理解:

links = ['http://xxx/abc{}/image{}'.format(x, y) for x, y in product(['x', 'y', 'z'], range(9, 12))]

答案 2 :(得分:0)

简单的尝试可能是以前的答案的替代

lst = ['http://xxx/abc%s/image%s.png'%(x,y) for x, y in [(j,i) for i in (9,10,11) for j in ('x', 'y', 'z')]]

省略rangeformat功能,以便更快地发挥作用。

分析 - 我比较了我的方式和Jkdc

发布的方式

我跑了 100000次,但意味着 itertools 方法在执行时间方面更快 -

from itertools import product
import time
from matplotlib import pyplot as plt
import numpy as np

prodct = []
native = []

def test():
    start = time.clock()
    lst = ['http://xxx/abc{}/image{}'.format(x, y) for x, y in product(('x', 'y', 'z'), range(9, 11))]
    end = time.clock()

    print '{0:.50f}'.format(end-start)
    prodct.append('{0:.50f}'.format(end-start))

    start1 = time.clock()
    lst = ['http://xxx/abc%s/image%s'%(x,y) for x, y in [(j,i) for i in (9,10,11) for j in ('x', 'y', 'z')]]
    end1 = time.clock()

    print '{0:.50f}'.format(end1-start1)
    native.append('{0:.50f}'.format(end1-start1))


for i in range(1,100000):
    test()


y = np.dot(np.array(native).astype(np.float),100000)
x= np.dot(np.array(prodct).astype(np.float),100000)

print np.mean(y)
print np.mean(x)

graph 并获得native(无模块)和itertools-product的结果,如下所示

本地2.1831179834

for itertools-product 1.60410432562