从字符串开头按正则表达式匹配和拆分
Match and split by regular expression from start of string
我正在尝试从头开始制作终端解析器(用于解析器组合器)。我的方法是在输入字符串上使用 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)
才能从匹配的 cons 中获取实际索引值。)
原来我遇到的问题确实是我的模式匹配。我试图在 (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)))
n.b.,我也不需要使用带有模式匹配的 regexp-match-positions
加星号版本,fwiw.
我正在尝试从头开始制作终端解析器(用于解析器组合器)。我的方法是在输入字符串上使用 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)
才能从匹配的 cons 中获取实际索引值。)
原来我遇到的问题确实是我的模式匹配。我试图在 (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)))
n.b.,我也不需要使用带有模式匹配的 regexp-match-positions
加星号版本,fwiw.