从字符串

时间:2017-10-17 16:37:23

标签: regex pattern-matching racket parser-combinators

我试图从头开始制作终端解析器(用于解析器组合器)。我的方法是在输入字符串上使用regexp-match-positions*,如果在第一个位置找到模式,那么我们输出拆分字符串。

到目前为止,这就是我所拥有的:

#lang racket/base

(require racket/match)

(define (make-terminal-parser pattern)
  (define (regexp-match-from-start pattern input)
    (match (regexp-match-positions* pattern input)
      [(list (cons 0 x) ...)
        (let ([index (car x)])
          (values (substring input 0 index)
                  (substring input index)))]

      [_ (error "Not found!")]))

  (lambda (input)
    (regexp-match-from-start pattern input)))

(define ALPHA (make-terminal-parser #rx"[a-zA-Z]"))

(ALPHA "hello")

我的ALPHA似乎无法正常工作,我认为这是因为模式匹配与任何事物无关。在REPL中,(regexp-match-positions* #rx"[a-zA-Z]" "hello")会输出我期望的内容('((0 . 1) (1 . 2) etc.)),因此我并不理解为什么它与(list (cons 0 x) ...)不匹配。如果我将正则表达式更改为#rx"h",那么它会正确地拆分字符串;但显然这太具体了。

(相关说明:我不明白为什么我需要(car x)从匹配的缺点中获取实际指数值。)

1 个答案:

答案 0 :(得分:0)

事实证明我遇到的问题确实与我的模式匹配有关。我试图在(list (cons 0 x) ...)上进行匹配,但文档暗示只匹配(0 . x)的一个或多个元素的列表(其中x是任意的)。那不是我想要的。

列表是一系列cons,因此我将匹配条件更改为(cons (cons 0 x) _),这样就可以提供我想要的内容。

这也解释了为什么我在之前的尝试中必须(car x)x中的(list (cons 0 x) ...)匹配项会匹配列表中每个cons的右侧元素,因此它会返回一个列表。例如'((0 . 1) (0 . 2) (0 . 3))匹配且x等于'(1 2 3)

所以,我的固定代码是:

(define (make-terminal-parser pattern)
  (define (regexp-match-from-start pattern input)
    (match (regexp-match-positions pattern input)
      [(cons (cons 0 index) _)
          (values (substring input 0 index)
                  (substring input index))]

      [_ (error "Not found!")]))

  (lambda (input)
    (regexp-match-from-start pattern input)))

n.b。,我也不需要使用带有模式匹配的regexp-match-positions的已加星标的版本,fwiw。