2015-11-20 35 views
2

我正在照片爬行器。 用戶可以指定正則表達式字符串來下載數據。我可以從正則表達式創建列表嗎?

當用戶輸入形式爲:

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塊中使用每個字符串嗎?

+0

添加更多的細節,你爲什麼要這些,你嘗試過什麼到目前爲止..它可以幫助我們找到更好更快的解決方案 – SIslam

+0

你可以在這裏使用循環 – The6thSense

+1

你的正則表達式是無效的,因爲'[9-11]'不是一個有效的字符類。我們需要更多關於您實際上想要實現的目標,以便能夠幫助您。 –

回答

6

如果你想要採取用戶給定的正則表達式作爲輸入並生成字符串列表,你可以使用這個庫sre_yield

然而,非常清楚,試圖解析每個possibl正則表達式的字符串可以非常快地失控。您需要確保用戶知道通配符和開放式或重複組對可能的匹配字符串的數量的影響。

作爲一個例子,你的正則表達式字符串: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'] 
+0

哇,我試過'sre_yield'。那很完美。我能夠達到我的目的。謝謝你的好意,我會照顧'。'。 –

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))] 
+0

你可以,但(a)這不會回答問題,因爲它不是從正則表達式創建字符串列表,並且(b)在我看來,嵌套循環會更直接。 –

+0

我相信它是有用的,無論如何,因爲(a)運沒有一個正則表達式,無論如何,從我猜他正在建立自己的事,這個答案提供了一個重要基石和(b)跨產品工具比嵌套循環多得多,表達和可擴展。 – spectras

+0

@spectras:我不同意(b)。 'itertools.product()'被嚴重過度使用,並且在幾乎所有情況下它都減少了可讀性,因爲它隱藏了單個循環變量與它們迭代的迭代之間的聯繫,並且不必要地增加了冗長度。 –

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 爲itertools產品1.60410432562

相關問題