Scheme ';匹配';球拍方案的形式。关于匹配序列的问题

Scheme ';匹配';球拍方案的形式。关于匹配序列的问题,scheme,racket,Scheme,Racket,我正在试验Racket的“匹配”形式,并希望匹配列表中的项目序列。每个项目都有特定的属性。例如,如果我想匹配与正则表达式(大致)相对应的数字和字符串的交替序列: #rx"([0-9]+ \"[a-zA-Z0-9]+\")+" 下面的代码似乎可以完成这项工作: (define (match-sequence L) (let ([n-lst '()] ; Used to collect numbers found. [s-lst '()]) ; Used to c

我正在试验Racket的“匹配”形式,并希望匹配列表中的项目序列。每个项目都有特定的属性。例如,如果我想匹配与正则表达式(大致)相对应的数字和字符串的交替序列:

#rx"([0-9]+ \"[a-zA-Z0-9]+\")+"
下面的代码似乎可以完成这项工作:

(define (match-sequence L)
  (let ([n-lst '()]     ; Used to collect numbers found.
        [s-lst '()])    ; Used to collect strings found.
    (define  (m-test L)
      (match L
             [(list-rest (? number? n) (? string? s)  ... (? m-test))
              (set! n-lst `(,@n-lst ,n))
              (set! s-lst `(,@s-lst ,(car s)))                
              (list (reverse n-lst) (reverse s-lst))]
             ['()
              #t]
             [else
             #f]))
    (m-test L)))
我意识到上面的#rx和代码并不完全匹配相同的序列,但这只是一个类比

这是最简洁的写法吗?

我尝试了如下模式:

(list ((? number? n) (? string? s)) ...)
而拉科并没有接受这一点

模式如下: (列表(?编号n)(?字符串s)…) 要求要匹配的列表的第一项为数字,所有其他项为字符串

我用几种方法尝试了准旋转和拼接,但都没有成功

一定有更优雅的队形,但我似乎找不到。任何帮助都将不胜感激。谢谢。

看起来您正在尝试将数字与其他数字分开,这并不难:

(define (match-sequence L)
  (match L
    [(list* (? number? n) (? string? s) ... rest)
     (let ([r (match-sequence rest)])
       (list `(,n ,@(car r)) `(,@s ,@(cadr r))))]
    ['() '(() ())]))
但在这种情况下,你可以使用,甚至更好:

但您可能希望将字符串子序列组合在一起,其中上面的代码更接近:

(define (match-sequence L)
  (match L
    [(list* (? number? n) (? string? s) ... rest)
     (let ([r (match-sequence rest)])
       (list `(,n ,@(car r)) `(,s ,@(cadr r))))]
    ['() '(() ())]))
在这种情况下,使用多个值比组成列表包装器更容易:

(define (match-sequence L)
  (match L
    [(list* (? number? n) (? string? s) ... rest)
     (let-values ([(ns ss) (match-sequence rest)])
       (values `(,n ,@ns) `(,s ,@ss)))]
    ['() (values '() '())]))

非常感谢。最后的
匹配序列是我想要的。项目的实际排序/排序很重要,因此分区不起作用。这个例子只是为了提问而简化的。实际应用程序正在将表单:text
text
等的HTML序列转换为Docbook
,因此实际代码可能会模糊其意图。使用
读取html
等可能会更好。但我现在的代码很好。希望
匹配
最终能够支持直接表达这一操作——底层实现已经足够灵活了。
(define (match-sequence L)
  (match L
    [(list* (? number? n) (? string? s) ... rest)
     (let-values ([(ns ss) (match-sequence rest)])
       (values `(,n ,@ns) `(,s ,@ss)))]
    ['() (values '() '())]))