【问题标题】:racket pattern matching do none greedy match球拍模式匹配做非贪婪匹配
【发布时间】:2014-07-06 11:06:17
【问题描述】:

Racket 语言中的模式匹配有 ... 进行贪婪匹配(匹配 0 或更多),如果我想匹配这样的东西怎么办:

#lang racket

(define (Modifier? t)  (equal? t "Modifier"))

(define (SimpleName? t)  (equal? t "SimpleName"))

(define (SimpleType? t)  (equal? t "SimpleType"))

(define (FieldDeclaration? t)  (equal? t "FieldDeclaration"))


(match (match '("FieldDeclaration" ("Modifier") ("Modifier") ("SimpleType") ("VariableDeclarationFragment" ("SimpleName") ("StringLiteral")))
   [(list (? FieldDeclaration? id) (? Modifier? m) ... (? SimpleType? t) (list _ (? SimpleName? n)) _ ...)
'yes]

   [else 'no] )

打印'no,而我期望'yes。我猜它是由... which do a greedy matching 引起的(只需在链接页面中搜索“贪婪”),但我不太确定......)

列表中可以有0到3个("Modifier"),那么这个表格怎么匹配?​​(其实XXX?函数里面还有很多事情要做,所以我有使用(? XXX? x) 的形式)

PS:是否可以extend the matching syntax 这样我可以使用n_m 之类的东西,这意味着匹配n 到m 次,就像正则表达式中的{n,m} 一样?

【问题讨论】:

    标签: regex pattern-matching racket


    【解决方案1】:

    其实... 并不贪心,你已经非常接近拥有它了 在职的。两个问题:

    首先,您的三个谓词是错误的。由于您的输入是 例如("Modifier") 不是 "Modifier",你想 匹配 (list "Modifier") 而不是 "Modifier"

    (define (Modifier? t)
      (equal? t (list "Modifier")))
    
    (define (SimpleName? t)
      (equal? t (list "SimpleName")))
    
    (define (SimpleType? t)
      (equal? t (list "SimpleType")))
    

    这个谓词没问题:

    (define (FieldDeclaration? t)
      (equal? t "FieldDeclaration"))
    

    第二,我认为你在最后部分有一个错误的结束括号 你的模板——应该是(list _ (? SimpleName? n) _ ...) 不是(list _ (? SimpleName? n)) _ ...

    这是完整的匹配表达式,我在其中添加了一些换行符 对我来说更具可读性:

    (match '("FieldDeclaration"
             ("Modifier") ("Modifier")
             ("SimpleType")
             ("VariableDeclarationFragment" ("SimpleName") ("StringLiteral")))
      [(list (? FieldDeclaration? id)
             (? Modifier? m) ...
             (? SimpleType? t)
             (list _ (? SimpleName? n) _ ...))
       'yes]
      [_ 'no])
    

    这打印出'yes

    【讨论】:

      【解决方案2】:

      Greg 写道,“实际上……并不贪婪”,但……是贪婪的,如以下示例所示:

      racket@match.rkt> (match '(1 2 7 3 4 5 3 6 7 3 8) [(list a ... 3 b ...) (list a b)])
      '((1 2 7 3 4 5 3 6 7) (8))
      
      (match '(1 2 7 3 4 5 3 6 7 3 8) [(list (? number? a) ... 3 b ...) (list a b)])
      '((1 2 7 3 4 5 3 6 7) (8))
      

      我原以为会看到 '((1 2 7) (4 5 3 6 7 3 8))。我在匹配我想要前缀的位置时遇到了问题,但我得到了贪婪的行为。

      【讨论】:

        猜你喜欢
        • 2013-06-09
        • 1970-01-01
        • 2017-10-16
        • 2012-11-17
        • 1970-01-01
        • 2015-02-11
        • 1970-01-01
        • 2011-08-29
        • 1970-01-01
        相关资源
        最近更新 更多