从字符串开头的正则表达式匹配和拆分
问题描述:
我试图从头开始编写终端解析器(用于解析器组合器)。我的方法是在输入字符串上使用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)
获得实际的指标值进行匹配的利弊。)
答
原来我是有确实与我的模式问题匹配。我试图在(list (cons 0 x) ...)
上匹配,但文档意味着只匹配(0 . x)
(其中x
是任意的)的一个或多个元素的列表。这不是我想要的。
列表是一系列cons
,所以我将我的匹配标准更改为(cons (cons 0 x) _)
,这给了我想要的。
这也解释了为什么我必须在我以前的尝试(car x)
。与(list (cons 0 x) ...)
匹配的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)))
注:另,我也不需要使用regexp-match-positions
带星版采用模式匹配,FWIW。