#lang racket/base
(require racket/list racket/contract)
(define (regexp-or . strings)
(apply string-append (add-between strings "|")))
(define (regexp-maybe . strings)
(format "(?:~a)?" (apply regexp-sequence strings)))
(define (regexp-star . strings)
(format "(?:~a)*" (apply regexp-sequence strings)))
(define (regexp-plus . strings)
(format "(?:~a)+" (apply regexp-sequence strings)))
(define (regexp-save . strings)
(format "(~a)" (apply regexp-sequence strings)))
(define (regexp-group string)
(format "(?:~a)" string))
(define (regexp-sequence #:start [start ""]
#:end [end ""]
#:between [between ""]
. strings)
(apply string-append
(append (list start)
(add-between (map regexp-group strings) between)
(list end))))
(define (regexp-multi . strings)
(format "(?m:~a)" (apply regexp-sequence strings)))
(provide/contract
[regexp-sequence
(->* [] [#:start string? #:end string? #:between string?]
#:rest (listof string?)
string?)]
[regexp-or (->* [string?] [] #:rest (listof string?) string?)]
[regexp-maybe (->* [string?] [] #:rest (listof string?) string?)]
[regexp-star (->* [string?] [] #:rest (listof string?) string?)]
[regexp-plus (->* [string?] [] #:rest (listof string?) string?)]
[regexp-save (->* [string?] [] #:rest (listof string?) string?)]
[regexp-multi (->* [string?] [] #:rest (listof string?) string?)])