2012-11-28 36 views
7

我正在嘗試學習球拍,並且正在嘗試重寫Python過濾器。我有以下兩個函數在我的代碼:從Python遷移到球拍(正則表達式庫和「球拍方式」)

def dlv(text): 
    """ 
    Returns True if the given text corresponds to the output of DLV 
    and False otherwise. 
    """ 
    return text.startswith("DLV") or \ 
      text.startswith("{") or \ 
      text.startswith("Best model") 

def answer_sets(text): 
    """ 
    Returns a list comprised of all of the answer sets in the given text. 
    """ 
    if dlv(text): 
     # In the case where we are processing the output of DLV, each 
     # answer set is a comma-delimited sequence of literals enclosed 
     # in {} 
     regex = re.compile(r'\{(.*?)\}', re.MULTILINE) 
    else: 
     # Otherwise we assume that the answer sets were generated by 
     # one of the Potassco solvers. In this case, each answer set 
     # is presented as a comma-delimited sequence of literals, 
     # terminated by a period, and prefixed by a string of the form 
     # "Answer: #" where "#" denotes the number of the answer set. 
     regex = re.compile(r'Answer: \d+\n(.*)', re.MULTILINE) 
    return regex.findall(text) 

從我可以告訴在拍第一功能的實現將是沿着以下的說法:

(define (dlv-input? text) 
    (regexp-match? #rx"^DLV|^{|^Best model" text)) 

這似乎工作正確。在第二函數的實現工作,我目前已經提出了以下(先從):

(define (answer-sets text) 
    (cond 
     [(dlv-input? text) (regexp-match* #rx"{(.*?)}" text)])) 

這是不正確的,因爲regexp-match*給出匹配正則表達式將字符串列表,其中包括大括號。有誰知道如何獲得與Python實現相同的行爲嗎?此外,如何使正則表達式「更好」的任何建議將不勝感激。

+1

我們可以問移民的原因嗎? –

+1

我編寫了原始過濾器來學習Python,並且正在採用類似的方法來學習球拍。所以這只是個人的「因爲我想要」的理由。 – ggelfond

+2

只需要注意:爲了準確匹配行爲,Python版本需要提升編譯的正則表達式值。 Python可能會緩存're.compile'的結果以獲得簡單的輸入,但您可能不想依賴此行爲來獲得性能關鍵的代碼。 – dyoo

回答

8

你非常接近。你只需要添加#:match-select cadr到您的通話regexp-match

(regexp-match* #rx"{(.*?)}" text #:match-select cadr) 

默認情況下,#:match-selectcar,返回整個匹配的字符串值。 cadr選擇第一組,caddr選擇第二組等。有關更多詳細信息,請參閱regexp-match* documentation

+0

非常感謝。 – ggelfond