首页 文章

球拍图案匹配多次

提问于
浏览
1

新手球拍编码器在这里 .

我有一个xexpr,我希望避免在某些元素之前和之后使用新行,例如 'eq 标记或 'figure 标记 .

假设我有以下内容:

(define tx1
  '(div (div "this is" "\n\n" (eq "y=x") "\n\n" "my equation" (eq "z=y"))
        "to fire" (eq "h=u") "up" "\n\n\n" (eq "tm=re") "\n" "this test" "\n"))

我想删除 'eq 标记周围的换行符字符串( "\n""\n\n""\n\n\n" )以生成以下内容:

(define result
  '(div (div "this is" (eq "y=x") "my equation" (eq "z=y"))
        "to fire" (eq "h=u") "up" (eq "tm=re") "this test" "\n"))

我的第一步是识别换行符 . 我发现模式匹配是一种可能的解决方案 .

(match tx1
  [(list a ... (regexp #rx"^\n+") b ...) `(,@a ,@b)]
  [(list a ...) `(,@a)])

但是,我必须在每次出现换行时运行此匹配函数一次 . 在这种情况下,我必须运行它3次 . 我可以每次测试结果,看看它是否已经改变,但这似乎是次优的 .

我尚未达到的第二步是将之前和之后的项目( ab )与带有 'eq 标记的列表进行匹配 . 第三步是找到子列表并递归这些子列表 .

我的问题是,首先是有更好的方法来解决这类问题吗?我相信可能有这样的解决方案 . 我的第二个问题是,如果匹配最好,是否有办法进行多次替换?我玩过缺点匹配,这在某种程度上有效,但它丢弃了第一项 .

谢谢 .

1 回答

  • 0

    我相信我找到了另一种解决方案 . 模式匹配是一个有趣的想法 - 它就像列表和表达式的正则表达式 . 但是,从新手的角度来看,它可以使用一些开发,使其与传统的正则表达式更紧密地对齐,例如搜索和替换函数等 .

    最终的解决方案是将输入xexpr转换为向量,并根据前面和前面的元素处理每个元素 .

    (define (clean-newlines elems [tags '(eq figure)])
      (define elements (merge-newlines elems))
      (define elems-vec (list->vector elements))
      (for/list ([(elem idx) (in-indexed elems-vec)])
        (cond
           ; skip first and last elements
          [(or (= idx 0) (= idx (sub1 (vector-length elems-vec)))) elem]
           ; process recursively if elem is a txexpr
          [(txexpr-elements? elem) (clean-newlines elem)]
           ; see if the element is a new line
          [(and (string? elem) (regexp-match #rx"^\n+" elem))
            ; get the previous and next elements
           (let ([prev (vector-ref elems-vec (sub1 idx))]
                 [next (vector-ref elems-vec (add1 idx))])
              ; if the previous or next element matches the tag, strip it
             (cond
               [(and (txexpr-elements? next) (member (get-tag next) tags)) "\n"]
               [(and (txexpr-elements? prev) (member (get-tag prev) tags)) "\n"]
               [else elem]))]
          [else elem])))
    

相关问题