Merge pull request #143 from AlexKnauth/string-split
add string-split-lens
This commit is contained in:
commit
78a65def02
|
@ -6,6 +6,7 @@
|
||||||
"arrow.rkt"
|
"arrow.rkt"
|
||||||
"isomorphism.rkt"
|
"isomorphism.rkt"
|
||||||
"mapper.rkt"
|
"mapper.rkt"
|
||||||
|
"string-split.rkt"
|
||||||
)
|
)
|
||||||
|
|
||||||
(provide (all-from-out "syntax.rkt"
|
(provide (all-from-out "syntax.rkt"
|
||||||
|
@ -14,4 +15,5 @@
|
||||||
"arrow.rkt"
|
"arrow.rkt"
|
||||||
"isomorphism.rkt"
|
"isomorphism.rkt"
|
||||||
"mapper.rkt"
|
"mapper.rkt"
|
||||||
|
"string-split.rkt"
|
||||||
))
|
))
|
||||||
|
|
|
@ -15,3 +15,4 @@ this library being backwards-compatible.
|
||||||
@include-section["arrow.scrbl"]
|
@include-section["arrow.scrbl"]
|
||||||
@include-section["isomorphism.scrbl"]
|
@include-section["isomorphism.scrbl"]
|
||||||
@include-section["mapper.scrbl"]
|
@include-section["mapper.scrbl"]
|
||||||
|
@include-section["string-split.scrbl"]
|
||||||
|
|
56
unstable/lens/string-split.rkt
Normal file
56
unstable/lens/string-split.rkt
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require racket/contract/base)
|
||||||
|
(provide (contract-out
|
||||||
|
[string-split-lens
|
||||||
|
(-> (or/c immutable-string? char? regexp?)
|
||||||
|
(lens/c immutable-string? (listof immutable-string?)))]
|
||||||
|
))
|
||||||
|
|
||||||
|
(require racket/match
|
||||||
|
racket/string
|
||||||
|
lens/base/main
|
||||||
|
lens/util/immutable
|
||||||
|
)
|
||||||
|
(module+ test
|
||||||
|
(require rackunit))
|
||||||
|
|
||||||
|
(define (string-split-lens sep)
|
||||||
|
(define sep-rx
|
||||||
|
(cond
|
||||||
|
[(string? sep) (regexp (regexp-quote sep))]
|
||||||
|
[(char? sep) (regexp (regexp-quote (string sep)))]
|
||||||
|
[(regexp? sep) sep]
|
||||||
|
[else (error 'bad)]))
|
||||||
|
(define (get str)
|
||||||
|
(map string->immutable-string (regexp-split sep-rx str)))
|
||||||
|
(define (set str lst)
|
||||||
|
(for ([s (in-list lst)])
|
||||||
|
(when (regexp-match? sep-rx s) ; this would violate the lens laws
|
||||||
|
(error 'string-split-lens "expected a string not matching ~v, given: ~v" sep s)))
|
||||||
|
(define seps (regexp-match* sep-rx str))
|
||||||
|
(match-define (cons fst rst) lst)
|
||||||
|
(string->immutable-string (string-append* fst (map string-append seps rst))))
|
||||||
|
(make-lens get set))
|
||||||
|
|
||||||
|
(module+ test
|
||||||
|
(define ws-lens (string-split-lens #px"\\s+"))
|
||||||
|
(check-equal? (lens-view ws-lens " foo bar baz \r\n\t")
|
||||||
|
'("" "foo" "bar" "baz" ""))
|
||||||
|
(check-equal? (lens-set ws-lens " foo bar baz \r\n\t" '("a" "b" "c" "d" "e"))
|
||||||
|
"a b c d \r\n\te")
|
||||||
|
(check-equal? (lens-view ws-lens "a b c d \r\n\te")
|
||||||
|
'("a" "b" "c" "d" "e"))
|
||||||
|
(check-equal? (lens-set ws-lens "a b c d \r\n\te" '("" "foo" "bar" "baz" ""))
|
||||||
|
" foo bar baz \r\n\t")
|
||||||
|
(define newline-lens (string-split-lens "\n"))
|
||||||
|
(check-equal? (lens-view newline-lens "a,b\nc,d\ne,f,g")
|
||||||
|
'("a,b" "c,d" "e,f,g"))
|
||||||
|
(check-equal? (lens-set newline-lens "a,b\nc,d\ne,f,g" '("1" "2" "3"))
|
||||||
|
"1\n2\n3")
|
||||||
|
(define comma-lens (string-split-lens #\,))
|
||||||
|
(check-equal? (lens-view comma-lens "a,b,c")
|
||||||
|
'("a" "b" "c"))
|
||||||
|
(check-equal? (lens-set comma-lens "a,b,c" '("1" "2" "3"))
|
||||||
|
"1,2,3")
|
||||||
|
)
|
26
unstable/lens/string-split.scrbl
Normal file
26
unstable/lens/string-split.scrbl
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#lang scribble/manual
|
||||||
|
|
||||||
|
@(require lens/doc-util/main)
|
||||||
|
|
||||||
|
@title{Splitting Strings}
|
||||||
|
|
||||||
|
@defmodule[unstable/lens/string-split]
|
||||||
|
|
||||||
|
@defproc[(string-split-lens [sep (or/c string? char? regexp?)]) lens?]{
|
||||||
|
Creates a lens that splits a string into multiple pieces like
|
||||||
|
@racket[regexp-split] or @racket[string-split].
|
||||||
|
@lenses-unstable-examples[
|
||||||
|
(lens-view (string-split-lens ",") "a,b,c")
|
||||||
|
(lens-set (string-split-lens ",") "a,b,c" '("1" "2" "3"))
|
||||||
|
]
|
||||||
|
Lenses created by @racket[string-split-lens] do not trim strings first, so that
|
||||||
|
when viewing a target that either starts or ends with something matching
|
||||||
|
@racket[sep], the view will include empty strings as the first or last element,
|
||||||
|
which is consistant with @racket[regexp-split] or @racket[string-split] with
|
||||||
|
@racket[#:trim? #f]. This is also more useful when using @racket[lens-set].
|
||||||
|
@lenses-unstable-examples[
|
||||||
|
(lens-view (string-split-lens ",") ",b,c")
|
||||||
|
(lens-set (string-split-lens ",") ",b,c" '("a" "b" "c"))
|
||||||
|
(lens-view (string-split-lens ",") "a,b,c,")
|
||||||
|
(lens-set (string-split-lens ",") "a,b,c," '("a" "b" "c" "d"))
|
||||||
|
]}
|
Loading…
Reference in New Issue
Block a user