2012-11-28 34 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