7

私は 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))

これは正しく動作しているようです。2番目の関数の実装に取り​​組んでおり、現在、次のことを考えています(最初に):

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

regexp-match*中括弧を含む、正規表現に一致する文字列のリストが表示されるため、これは正しくありません。Python 実装と同じ動作を取得する方法を知っている人はいますか? また、正規表現を「より良く」する方法についての提案は大歓迎です。

4

1 に答える 1

8

あなたはとても近くにいます。呼び出しに追加#:match-select cadrするだけです。regexp-match

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

デフォルトでは、一致した文字列全体を返す の#:match-select値があります。最初のグループを選択し、2 番目のグループを選択するなどです。詳細については、ドキュメントを参照してください。carcadrcaddrregexp-match*

于 2012-11-28T18:12:03.410 に答える