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")
,所以我该如何匹配此表单?(实际上,函数{{1}还有很多事情要做所以我必须使用XXX?
)
PS:是否可以extend the matching syntax这样我可以使用类似(? XXX? x)
的内容,这意味着匹配n到m次,就像正则表达式中的n_m
一样?
答案 0 :(得分:3)
实际上...
并不贪心,而且你非常接近它
工作。两个问题:
首先,你的三个谓词是错误的。既然你输入了
例如你想("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
。
答案 1 :(得分:0)
格雷格写道,"实际上......并不贪心#34;但......贪婪如下例所示:
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))。我在匹配我想要前缀的地方时遇到了问题,但是我得到了贪婪的行为。