从Python迁移到Racket(正则表达式库和“Racket Way”)

时间:2012-11-28 18:04:55

标签: python regex racket porting

我正在尝试学习Racket,并且正在尝试重写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)

据我所知,Racket中第一个函数的实现将是以下几点:

(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 个答案:

答案 0 :(得分:8)

你非常接近。您只需将#:match-select cadr添加到regexp-match来电:

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

默认情况下,#:match-select的值为car,返回整个匹配的字符串。 cadr选择第一个组,caddr选择第二个组等。有关详细信息,请参阅regexp-match* documentation