【问题标题】:'match' form in Racket Scheme. Question about matching sequences球拍方案中的“匹配”形式。关于匹配序列的问题
【发布时间】:2011-10-27 01:17:06
【问题描述】:

我正在尝试使用 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 和上面的代码并不完全匹配相同的序列,但这只是一个类比。

这是在 Racket 中最简洁的写法吗?

我试过这样的模式:

(list ((? number? n) (? string? s)) ...)

Racket 不接受这个。

如下模式: (list (?number?n) (?string?s) ...) 要求匹配列表的第一项为数字,所有其他项为字符串。

我尝试了多种方式进行准引用和拼接,但均未成功。

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

【问题讨论】:

    标签: scheme racket


    【解决方案1】:

    看起来就像你试图将数字与其他数字分开,这并不难:

    (define (match-sequence L)
      (match L
        [(list* (? number? n) (? string? s) ... rest)
         (let ([r (match-sequence rest)])
           (list `(,n ,@(car r)) `(,@s ,@(cadr r))))]
        ['() '(() ())]))
    

    但在这种情况下,您可以只使用filter,或者更好的是partition

    (partition number? '(1 "a" "b" 2 3 "c" "d" 4))
    

    但也许你想将字符串子序列组合在一起,上面的代码更接近:

    (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 '() '())]))
    

    【讨论】:

    • 谢谢。最后的match-sequence 是我所追求的。项目的实际排序/排序很重要,因此分区不会起作用。该示例被简化只是为了提出问题。实际的应用程序正在将以下形式的 HTML 序列: text <input type="radio" ...> text <input type="radio" ..> etc. 转换为 Docbook <orderedlist> 所以实际代码会掩盖意图。使用read-html 等可能会更好,但我现在的代码很好。
    • 希望match 最终会支持直接表达它正在做什么——底层实现已经足够灵活了。
    猜你喜欢
    • 2023-03-21
    • 2021-09-14
    • 2014-07-06
    • 2020-06-19
    • 1970-01-01
    • 2016-07-13
    • 2011-04-21
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多