2012-06-07 74 views
3

是否有可能實現一個字典作爲正則表達式和動作(帶參數)作爲值的鍵?在python中的正則表達式字典

爲例如

  1. key = "actionname 1 2", value = "method(1, 2)"
  2. key = "differentaction par1 par2", value = "appropriate_method(par1, par2)"

用戶類型的鍵,我需要執行與作爲用戶輸入的一部分提供的參數的匹配方法。

如果我們能夠在O(1)時間內完成查找,即使它不可能,至少我正在尋找解決方案來解決這個問題,這將是一件好事。

我將有幾百個正則表達式(比如說300)和匹配的參數化動作來執行。

我可以寫一個循環來實現這一點,但沒有任何優雅的方式來做到這一點,而無需使用一個for循環?

相關問題:Hashtable/dictionary/map lookup with regular expressions

+1

如果什麼輸入匹配多個正則表達式? – Eric

+0

我只需要第一場比賽。有沒有匹配的列表,但不是必需的。 – 18bytes

+1

相關問題:http://stackoverflow.com/questions/481266/is-there-a-way-in-python-to-apply-a-list-of-regex-patterns-that-are-stored-in-我的回答一個 –

回答

7

是的,這是完全有可能:

import re 
dict = {} 
dict[re.compile('actionname (\d+) (\d+)')] = method 
dict[re.compile('differentaction (\w+) (\w+)')] = appropriate_method 

def execute_method_for(str): 
    #Match each regex on the string 
    matches = (
     (regex.match(str), f) for regex, f in dict.iteritems() 
    ) 

    #Filter out empty matches, and extract groups 
    matches = (
     (match.groups(), f) for match, f in matches if match is not None 
    ) 


    #Apply all the functions 
    for args, f in matches: 
     f(*args) 
+0

是否可以在正則表達式中使用命名組並將其與等效的命名方法參數進行映射? – 18bytes

+0

原則上,是的。我不記得你如何遍歷命名組。 – Eric

+2

@devsunder:好的知道了:使用'groupdict()'代替'組()'和'** args'到位'* args' – Eric

4

當然,你的字典的值可以是Python函數。

您的匹配函數可以嘗試將您的字符串與每個鍵匹配,並在匹配時執行相應的函數。在最好的情況下,這將是線性的,但如果你想使用正則表達式,我認爲你不會得到更好的結果。

但看着你的例子數據,我認爲你應該重新考慮你是否需要正則表達式。也許你可以解析你的輸入字符串,例如<procedure-name> <parameter>+,然後通過它的名稱(簡單字符串)查找適當的過程,可以是O(1)

+0

當有比賽,我想調用與提供的參數,我正在尋找一個優雅的方式來做到這一點的方法。 – 18bytes

2

不幸的是,這是不可能的。您需要遍歷正則表達式,以瞭解他們是否匹配。在字典中查找將O(1)雖然(但不解決您的問題)。

0

恕我直言,你問的錯誤的問題

  1. 你問是否有一個優雅的方式來做到這一點。答案:最優雅的方式是最明顯的方式。代碼將被修改爲10倍到20倍。因此,如果你寫的東西「優雅」這是難以閱讀和快速地瞭解你,你已經破壞之後,你的傢伙誰擁有以某種方式修改它。

  2. 更好的代碼:

這裏的另一個復讀是這樣的:

matches = ((regex.match(str), f) for regex, f in dict.iteritems()) 

這是功能相當的(重要的是,在Python方面同樣生成的字節碼)到:

# IMHO 'regex' var should probably be named 'pattern' since it's type is <sre.SRE_Pattern> 

for pattern, func in dictname.items(): 
    if pattern.match(str): 
     func() 

但是,下面的樣品是巨大EAS更加容易閱讀和理解一目瞭然

我道歉(少許),如果你是誰是代碼,甚至稍微羅嗦比你認爲它可能是得罪了那些人之一。我的標準,以及PEP-8中提到的Guido's,最清晰的代碼是最好的代碼。