정규 표현식
정규 표현식 (Regular Expressions)
정규 표현식은 문자열이나 바이트 문자열로 지정하며, Unix 유틸리티 egrep이나 Perl과 같은 패턴 언어를 사용해요. regexp 값으로 컴파일하면 문자열 형태에 비해 regexp-match 같은 함수에서 더 효율적으로 쓸 수 있어요.
출처: Racket Reference
본문
4.8 정규 표현식
정규 표현식은 The Racket Guide의 "Regular Expressions" 절에서 소개돼요.
정규 표현식은 Unix 유틸리티 egrep이나 Perl과 같은 패턴 언어를 문자열이나 바이트 문자열로 지정해요. 문자열로 지정된 패턴은 문자 regexp 매처를 만들고, 바이트 문자열 패턴은 바이트 regexp 매처를 만들어요. 문자 regexp를 바이트 문자열이나 입력 포트와 함께 쓰면 일치하는 문자 스트림의 UTF-8 인코딩(Encodings and Locales 참고)과 매치되고, 바이트 regexp를 문자 문자열과 함께 쓰면 그 문자열의 UTF-8 인코딩의 바이트와 매치돼요.
문자열이나 바이트 문자열로 표현된 정규 표현식은 regexp 값으로 컴파일될 수 있고, regexp-match 같은 함수에서 문자열이나 바이트 문자열 형태보다 더 효율적으로 사용돼요. regexp 와 byte-regexp 프로시저는 각각 문자열이나 바이트 문자열을 egrep에 가장 호환되는 정규 표현식 문법으로 regexp 값으로 변환해요. pregexp 와 byte-pregexp 프로시저는 Perl에 더 호환되는 약간 다른 정규 표현식 문법으로 regexp 값을 만들어요.
두 regexp 값은 같은 소스를 갖고, 같은 패턴 언어를 사용하며, 둘 다 문자 regexp이거나 둘 다 바이트 regexp일 때 equal? 해요.
리터럴 또는 출력된 regexp 값은 #rx 나 #px 로 시작해요. 정규 표현식의 read에 대한 내용은 "Reading Regular Expressions"를, print에 대한 내용은 "Printing Regular Expressions"를 참고해요. 기본 리더가 만들어낸 regexp 값은 read-syntax 모드에서 인터닝돼요.
Racket의 BC 변형에서 regexp 값의 내부 크기는 32킬로바이트로 제한돼요. 이 제한은 대략 32,000개의 리터럴 문자나 5,000개의 연산자를 가진 소스 문자열에 해당해요.
4.8.1 Regexp 문법
다음 문법 명세는 정규 표현식을 나타내는 문자열의 내용을 설명해요. 해당 문자열의 문법은 추가 이스케이프 문자를 포함할 수 있어요. 예를 들어 정규 표현식 (.*)\1 은 문자열 "(.*)\\1" 이나 regexp 상수 #rx"(.*)\\1" 로 표현할 수 있어요. 정규 표현식의 \ 는 문자열이나 regexp 상수에 포함되려면 이스케이프되어야 해요.
regexp 와 pregexp 문법은 공통된 핵심을 공유해요:
‹regexp› ::= ‹pces› Match ‹pces›
| ‹regexp› | ‹regexp› Match either ‹regexp›, try left first (ex1)
‹pces› ::= Match empty
| ‹pce› ‹pces› Match ‹pce› followed by ‹pces›
‹pce› ::= ‹repeat› Match ‹repeat›, longest possible (ex3)
| ‹repeat› ? Match ‹repeat›, shortest possible (ex6)
| ‹atom› Match ‹atom› exactly once
‹repeat› ::= ‹atom› * Match ‹atom› 0 or more times (ex3)
| ‹atom› + Match ‹atom› 1 or more times (ex4)
| ‹atom› ? Match ‹atom› 0 or 1 times (ex5)
‹atom› ::= ( ‹regexp› ) Match sub-expression ‹regexp› and report (ex11)
| [ ‹rng› ] Match any character in ‹rng› (ex2)
| [^ ‹crng› ] Match any character not in ‹crng› (ex12)
| . Match any (except newline in multi mode) (ex13)
| ^ Match start (or after newline in multi mode) (ex14)
| $ Match end (or before newline in multi mode) (ex15)
| ‹literal› Match a single literal character (ex1)
| (? ‹mode› : ‹regexp› ) Match ‹regexp› using ‹mode› (ex35)
| (?> ‹regexp› ) Match ‹regexp›, only first possible
| ‹look› Match empty if ‹look› matches
| (? ‹tst› ‹pces› | ‹pces› )
Match 1st ‹pces› if ‹tst›, else 2nd ‹pces› (ex36)
| (? ‹tst› ‹pces› ) Match ‹pces› if ‹tst›, empty if not ‹tst›
| \ at end of pattern Match the nul character (ASCII 0)
‹crng› ::= ‹rng› ‹crng› contains everything in ‹rng›
| ^ ‹crng› ‹crng› contains ^ and everything in ‹crng› (ex37)
‹rng› ::= ] ‹rng› contains ] only (ex27)
| - ‹rng› contains - only (ex28)
| ‹mrng› ‹rng› contains everything in ‹mrng›
| ‹mrng› - ‹rng› contains - and everything in ‹mrng›
‹mrng› ::= ] ‹lrng› ‹mrng› contains ] and everything in ‹lrng› (ex29)
| - ‹lrng› ‹mrng› contains - and everything in ‹lrng› (ex29)
| ‹lirng› ‹mrng› contains everything in ‹lirng›
‹lirng› ::= ‹riliteral› ‹lirng› contains a literal character
| ‹riliteral› - ‹rliteral› ‹lirng› contains Unicode range inclusive (ex22)
| ‹lirng› ‹lrng› ‹lirng› contains everything in both
‹lrng› ::= ^ ‹lrng› contains ^ (ex30)
| ‹rliteral› - ‹rliteral› ‹lrng› contains Unicode range inclusive
| ^ ‹lrng› ‹lrng› contains ^ and more
| ‹lirng› ‹lrng› contains everything in ‹lirng›
‹look› ::= (?= ‹regexp› ) Match if ‹regexp› matches (ex31)
| (?! ‹regexp› ) Match if ‹regexp› doesn't match (ex32)
| (?<= ‹regexp› ) Match if ‹regexp› matches preceding (ex33)
| (?<! ‹regexp› ) Match if ‹regexp› doesn't match preceding (ex34)
‹tst› ::= ( ‹n› ) True if ‹n›th ( has a match
| ‹look› True if ‹look› matches (ex36)
‹mode› ::= Like the enclosing mode
| ‹mode› i Like ‹mode›, but case-insensitive (ex35)
| ‹mode› -i Like ‹mode›, but sensitive
| ‹mode› s Like ‹mode›, but not in multi mode
| ‹mode› -s Like ‹mode›, but in multi mode
| ‹mode› m Like ‹mode›, but in multi mode
| ‹mode› -m Like ‹mode›, but not in multi mode
다음은 regexp 의 문법을 완성하는데, 여기서 { 와 } 를 리터럴로, 범위 안의 \ 를 리터럴로, 범위 밖의 \ 를 리터럴 생성자로 취급해요.
‹literal› ::= Any character except ( ) * + ? [ . ^ \ |
| \ ‹aliteral› Match ‹aliteral› (ex21)
‹aliteral› ::= Any character
‹riliteral› ::= Any character except ] - ^
‹rliteral› ::= Any character except ] -
다음은 pregexp 의 문법을 완성하는데, { 와 } 를 경계 반복(bounded repetition)에 사용하고, 범위 안팎 모두에서 \ 를 메타문자에 사용해요.
‹repeat› ::= ... (regexp와 같은 ... 반복 형태)
| ‹atom› {‹n›} Match ‹atom› exactly ‹n› times (ex7)
| ‹atom› {‹n›,} Match ‹atom› ‹n› or more times (ex8)
| ‹atom› {,‹m›} Match ‹atom› between 0 and ‹m› times (ex9)
| ‹atom› {‹n›,‹m›} Match ‹atom› between ‹n› and ‹m› times (ex10)
| ‹atom› {} Match ‹atom› 0 or more times
‹atom› ::= ... (regexp와 같은 ... 원자 형태)
| \ ‹n› Match latest reported match for ‹n›th ( (ex16)
| ‹class› Match any character in ‹class›
| \b Match \w* boundary (ex17)
| \B Match where \b does not (ex18)
| \p{‹property›} Match (UTF-8 encoded) in ‹property› (ex19)
| \P{‹property›} Match (UTF-8 encoded) not in ‹property› (ex20)
| \X Match (UTF-8 encoded) grapheme cluster
‹literal› ::= Any character except ( ) * + ? [ ] { } . ^ \ |
| \ ‹aliteral› Match ‹aliteral› (ex21)
‹aliteral› ::= Any character except a-z A-Z 0-9
‹lirng› ::= ... (regexp와 같은 ... 범위 형태)
| ‹class› ‹lirng› contains all characters in ‹class›
| ‹posix› ‹lirng› contains all characters in ‹posix› (ex26)
| \ ‹eliteral› ‹lirng› contains ‹eliteral›
‹riliteral› ::= Any character except ] \ - ^
‹rliteral› ::= Any character except ] \ -
‹eliteral› ::= Any character except a-z A-Z
‹class› ::= \d Contains 0-9 (ex23)
| \D Contains characters not in \d
| \w Contains a-z A-Z 0-9 _ (ex24)
| \W Contains characters not in \w
| \s Contains space, tab, newline, formfeed, return (ex25)
| \S Contains characters not in \s
‹posix› ::= [:alpha:] Contains a-z A-Z
| [:upper:] Contains A-Z
| [:lower:] Contains a-z (ex26)
| [:digit:] Contains 0-9
| [:xdigit:] Contains 0-9 a-f A-F
| [:alnum:] Contains a-z A-Z 0-9
| [:word:] Contains a-z A-Z 0-9 _
| [:blank:] Contains space and tab
| [:space:] Contains space, tab, newline, formfeed, return
| [:graph:] Contains all ASCII characters that use ink
| [:print:] Contains space, tab, and ASCII ink users
| [:cntrl:] Contains all characters with scalar value < 32
| [:ascii:] Contains all ASCII characters
‹property› ::= ‹category› Includes all characters in ‹category›
| ^ ‹category› Includes all characters not in ‹category›
대소문자를 구분하지 않는 모드에서 \‹n› 형태의 역참조(backreference)는 ASCII 문자의 경우에만 대소문자 구분 없이 매치돼요.
Unicode 카테고리는 다음과 같아요.
‹category› ::= Ll Letter, lowercase (ex19)
| Lu Letter, uppercase
| Lt Letter, titlecase
| Lm Letter, modifier
| L& Union of Ll, Lu, Lt, and Lm
| Lo Letter, other
| L Union of L& and Lo
| Nd Number, decimal digit
| Nl Number, letter
| No Number, other
| N Union of Nd, Nl, and No
| Ps Punctuation, open
| Pe Punctuation, close
| Pi Punctuation, initial quote
| Pf Punctuation, final quote
| Pc Punctuation, connector
| Pd Punctuation, dash
| Po Punctuation, other
| P Union of Ps, Pe, Pi, Pf, Pc, Pd, and Po
| Mn Mark, non-spacing
| Mc Mark, spacing combining
| Me Mark, enclosing
| M Union of Mn, Mc, and Me
| Sc Symbol, currency
| Sk Symbol, modifier
| Sm Symbol, math
| So Symbol, other
| S Union of Sc, Sk, Sm, and So
| Zl Separator, line
| Zp Separator, paragraph
| Zs Separator, space
| Z Union of Zl, Zp, and Zs
| Cc Other, control
| Cf Other, format
| Cs Other, surrogate
| Cn Other, not assigned
| Co Other, private use
| C Union of Cc, Cf, Cs, Cn, and Co
| . Union of all Unicode categories
. 을 가진 문자 regexp를 바이트 문자열이나 입력 포트와 함께 쓰면 .는 입력에서 유효한 UTF-8 인코딩에만 매치돼요. 바이트 regexp의.은 어떤 바이트(멀티 모드에서는 새 줄 제외)와도 매치돼요.\P나\p로 지정된 속성은 문자 regexp든 바이트 regexp든 유효한 UTF-8 인코딩에만 매치돼요. 마찬가지로\X` 는 유효한 UTF-8 인코딩 시퀀스에만 매치되고, 시퀀스의 접두사에는 매치하지 않아요(접두사만 매치해도 패턴의 나머지가 남은 입력과 매치될 수 있어도). 단, 그래핌 클러스터 시퀀스는 유효하지 않은 UTF-8 인코딩으로 끝날 수 있어요.
예:
> (regexp-match #rx"a|b" "cat") ; ex1
'("a")
> (regexp-match #rx"[at]" "cat") ; ex2
'("a")
> (regexp-match #rx"ca*[at]" "caaat") ; ex3
'("caaat")
> (regexp-match #rx"ca+[at]" "caaat") ; ex4
'("caaat")
> (regexp-match #rx"ca?t?" "ct") ; ex5
'("ct")
> (regexp-match #rx"ca*?[at]" "caaat") ; ex6
'("ca")
> (regexp-match #px"ca{2}" "caaat") ; ex7, uses #px
'("caa")
> (regexp-match #px"ca{2,}t" "catcaat") ; ex8, uses #px
'("caat")
> (regexp-match #px"ca{,2}t" "caaatcat") ; ex9, uses #px
'("cat")
> (regexp-match #px"ca{1,2}t" "caaatcat") ; ex10, uses #px
'("cat")
> (regexp-match #rx"(c<*)(a*)" "caat") ; ex11
'("caa" "c" "aa")
> (regexp-match #rx"[^ca]" "caat") ; ex12
'("t")
> (regexp-match #rx".(.)." "cat") ; ex13
'("cat" "a")
> (regexp-match #rx"^a|^c" "cat") ; ex14
'("c")
> (regexp-match #rx"a$|t$" "cat") ; ex15
'("t")
> (regexp-match #px"c(.)\\1t" "caat") ; ex16, uses #px
'("caat" "a")
> (regexp-match #px".\\b." "cat in hat") ; ex17, uses #px
'("t ")
> (regexp-match #px".\\B." "cat in hat") ; ex18, uses #px
'("ca")
> (regexp-match #px"\\p{Ll}" "Cat") ; ex19, uses #px
'("a")
> (regexp-match #px"\\P{Ll}" "cat!") ; ex20, uses #px
'("!")
> (regexp-match #rx"\\|" "c|t") ; ex21
'("|")
> (regexp-match #rx"[a-f]*" "cat") ; ex22
'("ca")
> (regexp-match #px"[a-f\\d]*" "1cat") ; ex23, uses #px
'("1ca")
> (regexp-match #px" [\\w]" "cat hat") ; ex24, uses #px
'(" h")
> (regexp-match #px"t[\\s]" "cat\nhat") ; ex25, uses #px
'("t\n")
> (regexp-match #px"[[:lower:]]+" "Cat") ; ex26, uses #px
'("at")
> (regexp-match #rx"[]]" "c]t") ; ex27
'("]")
> (regexp-match #rx"[-]" "c-t") ; ex28
'("-")
> (regexp-match #rx"[]a[]+" "c[a]t") ; ex29
'("[a]")
> (regexp-match #rx"[a^]+" "ca^t") ; ex30
'("a^")
> (regexp-match #rx".a(?=p)" "cat nap") ; ex31
'("na")
> (regexp-match #rx".a(?!t)" "cat nap") ; ex32
'("na")
> (regexp-match #rx"(?<=n)a." "cat nap") ; ex33
'("ap")
> (regexp-match #rx"(?<!c)a." "cat nap") ; ex34
'("ap")
> (regexp-match #rx"(?i:a)[tp]" "cAT nAp") ; ex35
'("Ap")
> (regexp-match #rx"(?(?<=c)a|b)+" "cabal") ; ex36
'("ab")
> (regexp-match #rx"[^^]+" "^cat^") ; ex37
'("cat")
Changed in version 8.15.0.8 of package base: \X 그래핌 클러스터 패턴이 추가됐어요.
4.8.2 추가적인 문법 제약
문법에 매치되는 것에 더해, 정규 표현식은 두 가지 문법적 제약을 충족해야 해요.
‹repeat›이‹atom›?가 아닌 경우,‹atom›은 빈 시퀀스와 매치되면 안 돼요.(?<=‹regexp›)이나(?<!‹regexp›)에서‹regexp›는 제한된(bounded) 시퀀스에만 매치되어야 해요.
이 제약들은 다음 타입 시스템으로 문법적으로 검사돼요. 타입 [n, m] 은 n과 m 사이의 문자 수와 매치하는 표현식에 해당해요. (‹regexp›) 규칙에서 ‹n› 은 여는 괄호가 매치 보고를 수집하는 ‹n›번째 여는 괄호가 되는 그런 수를 뜻해요. 역참조 패턴 \‹n› 에 대해서는 비-빈성(non-emptiness)이 추론되어, 역참조를 반복 패턴에 사용할 수 있어요. 역참조들 사이의 상호 의존의 경우, 추론은 비-빈성을 최대화하는 고정점을 선택해요. 역참조에는 유한성이 추론되지 않아요(즉, 역참조는 임의로 큰 시퀀스와 매치되는 것으로 가정돼요). 역참조가 참조하는 그룹 안에 역참조가 있는 것을 금지하는 문법적 제약은 없어요. 다만 그런 자기 참조는 매치가 불가능한 패턴을 만들 수 있어요((.\\1) 의 경우, 물론 (^.|\\1){2} 는 같은 두 문자로 시작하는 입력과 매치되지만).
다음은 타입 규칙이에요:
‹regexp›1 : [n1, m1] ‹regexp›2 : [n2, m2]
‹regexp›1 | ‹regexp›2 : [min(n1, n2), max(m1, m2)]
‹pce› : [n1, m1] ‹pces› : [n2, m2]
‹pce›‹pces› : [n1+n2, m1+m2]
‹repeat› : [n, m]
‹repeat›? : [0, m]
‹atom› : [n, m] n > 0
‹atom›* : [0, ∞]
‹atom› : [n, m] n > 0
‹atom›+ : [1, ∞]
‹atom› : [n, m]
‹atom›? : [0, m]
‹atom› : [n, m] n > 0
‹atom›{‹n›} : [n*‹n›, m*‹n›]
‹atom› : [n, m] n > 0
‹atom›{‹n›,} : [n*‹n›, ∞]
‹atom› : [n, m] n > 0
‹atom›{,‹m›} : [0, m*‹m›]
‹atom› : [n, m] n > 0
‹atom›{‹n›,‹m›} : [n*‹n›, m*‹m›]
‹regexp› : [n, m]
(‹regexp›) : [n, m] α‹n›=n
‹regexp› : [n, m]
(?‹mode›:‹regexp›) : [n, m]
‹regexp› : [n, m]
(?=‹regexp›) : [0, 0]
‹regexp› : [n, m]
(?!‹regexp›) : [0, 0]
‹regexp› : [n, m] m < ∞
(?<=‹regexp›) : [0, 0]
‹regexp› : [n, m] m < ∞
(?<!‹regexp›) : [0, 0]
‹regexp› : [n, m]
(?>‹regexp›) : [n, m]
‹tst› : [n0, m0] ‹pces›1 : [n1, m1] ‹pces›2 : [n2, m2]
(?‹tst›‹pces›1|‹pces›2) : [min(n1, n2), max(m1, m2)]
‹tst› : [n0, m0] ‹pces› : [n1, m1]
(?‹tst›‹pces›) : [0, m1]
(‹n›) : [α‹n›, ∞]
[‹rng›] : [1, 1]
[^‹rng›] : [1, 1]
. : [1, 1]
^ : [0, 0]
$ : [0, 0]
‹literal› : [1, 1]
\‹n› : [α‹n›, ∞]
‹class› : [1, 1]
\b : [0, 0]
\B : [0, 0]
\p{‹property›} : [1, 6]
\P{‹property›} : [1, 6]
\X : [1, ∞]
4.8.3 Regexp 생성자
procedure
(regexp? v) → boolean?
v : any/c
v 가 regexp 나 pregexp 로 만들어진 regexp 값이면 #t, 그렇지 않으면 #f 를 반환해요.
procedure
(pregexp? v) → boolean?
v : any/c
v 가 pregexp(이지 regexp)로 만들어진 regexp 값이면 #t, 그렇지 않으면 #f 를 반환해요.
procedure
(byte-regexp? v) → boolean?
v : any/c
v 가 byte-regexp 나 byte-pregexp 로 만들어진 regexp 값이면 #t, 그렇지 않으면 #f 를 반환해요.
procedure
(byte-pregexp? v) → boolean?
v : any/c
v 가 byte-pregexp(이지 byte-regexp)로 만들어진 regexp 값이면 #t, 그렇지 않으면 #f 를 반환해요.
procedure
(regexp str) → regexp?
str : string?
(regexp str handler) → any
str : string?
handler : (or/c #f (string? . -> . any))
정규 표현식의 문자열 표현(Regexp 문법의 문법을 사용)을 받아 regexp 값으로 컴파일해요. 다른 정규 표현식 프로시저들은 매칭 패턴으로 문자열이나 regexp 값을 받아들여요. 정규 표현식 문자열을 여러 번 사용한다면, 문자열을 각각 사용하는 대신 문자열을 한 번 regexp 값으로 컴파일해 반복 매치에 쓰는 것이 더 빨라요.
handler 가 제공되고 #f 가 아니면, str 이 정규 표현식의 유효한 표현이 아닐 때 호출되어 그 결과를 반환해요. handler 의 인자는 str 의 문제를 설명하는 문자열이에요. handler 가 #f 이거나 제공되지 않으면 exn:fail:contract 예외가 발생해요.
object-name 프로시저는 regexp 값의 소스 문자열을 반환해요.
예:
> (regexp "ap*le")
#rx"ap*le"
> (object-name #rx"ap*le")
"ap*le"
> (regexp "+" (λ (s) (list s)))
'("`+` follows nothing in pattern")
Changed in version 6.5.0.1 of package base: handler 인자가 추가됐어요.
procedure
(pregexp str) → pregexp?
str : string?
(pregexp str handler) → any
str : string?
handler : (or/c #f (string? . -> . any))
regexp 와 같지만, 약간 다른 문법을 사용해요(Regexp 문법 참고). 결과는 regexp 의 결과처럼 regexp-match 등과 함께 사용할 수 있어요.
예:
> (pregexp "ap*le")
#px"ap*le"
> (regexp? #px"ap*le")
#t
> (pregexp "+" (λ (s) (vector s)))
'#("`+` follows nothing in pattern")
Changed in version 6.5.0.1 of package base: handler 인자가 추가됐어요.
procedure
(byte-regexp bstr) → byte-regexp?
bstr : bytes?
(byte-regexp bstr handler) → any
bstr : bytes?
handler : (or/c #f (bytes? . -> . any))
정규 표현식의 바이트-문자열 표현(Regexp 문법의 문법을 사용)을 받아 byte-regexp 값으로 컴파일해요.
handler 가 제공되면, bstr 이 정규 표현식의 유효한 표현이 아닐 때 호출되어 그 결과를 반환해요.
object-name 프로시저는 regexp 값의 소스 바이트 문자열을 반환해요.
예:
> (byte-regexp #"ap*le")
#rx#"ap*le"
> (object-name #rx#"ap*le")
#"ap*le"
> (byte-regexp "ap*le")
byte-regexp: contract violation
expected: bytes?
given: "ap*le"
> (byte-regexp #"+" (λ (s) (list s)))
'("`+` follows nothing in pattern")
Changed in version 6.5.0.1 of package base: handler 인자가 추가됐어요.
procedure
(byte-pregexp bstr) → byte-pregexp?
bstr : bytes?
(byte-pregexp bstr handler) → any
bstr : bytes?
handler : (or/c #f (bytes? . -> . any))
byte-regexp 와 같지만, 약간 다른 문법을 사용해요(Regexp 문법 참고). 결과는 byte-regexp 의 결과처럼 regexp-match 등과 함께 사용할 수 있어요.
예:
> (byte-pregexp #"ap*le")
#px#"ap*le"
> (byte-pregexp #"+" (λ (s) (vector s)))
'#("`+` follows nothing in pattern")
Changed in version 6.5.0.1 of package base: handler 인자가 추가됐어요.
procedure
(regexp-quote str [case-sensitive?]) → string?
str : string?
case-sensitive? : any/c = #t
(regexp-quote bstr [case-sensitive?]) → bytes?
bstr : bytes?
case-sensitive? : any/c = #t
str 의 리터럴 문자 시퀀스나 bstr 의 바이트 시퀀스와 매치하기 위해 regexp 와 함께 쓰기에 적합한 문자열이나 바이트 문자열을 만들어요. case-sensitive? 가 참(기본값)이면, 결과 regexp는 str 이나 bstr 의 문자를 대소문자 구분하여 매치하고, 그렇지 않으면 대소문자 구분 없이 매치해요.
예:
> (regexp-match "." "apple.scm")
'("a")
> (regexp-match (regexp-quote ".") "apple.scm")
'(".")
procedure
(pregexp-quote str [case-sensitive?]) → string?
str : string?
case-sensitive? : any/c = #t
(pregexp-quote bstr [case-sensitive?]) → bytes?
bstr : bytes?
case-sensitive? : any/c = #t
regexp-quote 와 같지만, pregexp 와 함께 쓰도록 의도됐어요. 입력의 영숫자가 아니고 밑줄이 아닌 모든 문자를 이스케이프해요.
Added in version 8.11.1.9 of package base.
procedure
(regexp-max-lookbehind pattern) → exact-nonnegative-integer?
pattern : (or/c regexp? byte-regexp?)
pattern 이 매치를 결정하기 위해 매치의 시작 위치 전에 조사할 수 있는 최대 바이트 수를 반환해요. 예를 들어 패턴 (?<=abc)d 는 일치하는 d 앞의 세 바이트를 조사하고, e(?<=a..)d 는 일치하는 ed 앞의 두 바이트를 조사해요. ^ 패턴은 현재 위치가 입력의 시작인지 줄의 시작인지 결정하기 위해 앞의 바이트를 조사할 수 있어요.
예:
> (regexp-max-lookbehind #rx#"(?<=abc)d")
3
> (regexp-max-lookbehind #rx#"e(?<=a..)d")
2
> (regexp-max-lookbehind #rx"^")
1
procedure
(regexp-capture-group-count pattern) → exact-nonnegative-integer?
pattern : (or/c regexp? byte-regexp?)
pattern 안의 캡처 그룹 수를 반환해요. 이는 pattern 에 대한 성공한 매치에서 regexp-match 가 반환하는 리스트의 길이보다 하나 적은 값에 해당해요.
예:
> (regexp-capture-group-count #rx"abcd")
0
> (regexp-capture-group-count #rx"a(b*c)(d*)")
2
> (regexp-capture-group-count #rx"a(?:bc)*d")
0
Added in version 8.15.0.8 of package base.
4.8.4 Regexp 매칭
procedure
(regexp-match pattern input [start-pos end-pos output-port input-prefix])
→
(if (and (or (string? pattern) (regexp? pattern))
(or (string? input) (path? input)))
(or/c #f (cons/c string? (listof (or/c string? #f))))
(or/c #f (cons/c bytes? (listof (or/c bytes? #f)))))
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
output-port : (or/c output-port? #f) = #f
input-prefix : bytes? = #""
pattern (문자열, 바이트 문자열, regexp 값, 또는 byte-regexp 값)을 input 의 일부에 한 번 매치하려고 시도해요. 매처는 매치되고 입력의 시작(start-pos 이후)에 가장 가까운 input 의 일부를 찾아요.
input 이 경로(path)이면, pattern 이 바이트 문자열이나 바이트 기반 regexp일 때 path->bytes 로 바이트 문자열로 변환돼요. 그렇지 않으면 input 은 path->string 으로 문자열로 변환돼요.
선택적 start-pos 와 end-pos 인자는 매칭할 input 의 일부를 선택해요. 기본값은 전체 문자열 또는 파일 끝까지의 스트림이에요. input 이 문자열이면 start-pos 는 문자 위치이고, input 이 바이트 문자열이면 start-pos 는 바이트 위치이며, input 이 입력 포트이면 start-pos 는 매칭을 시작하기 전에 건너뛸 바이트 수예요. end-pos 인자는 #f 일 수 있는데, 문자열의 끝이나 스트림의 파일 끝에 해당해요. 그렇지 않으면 start-pos 처럼 문자나 바이트 위치예요. input 이 입력 포트이고 start-pos 바이트를 건너뛰기 전에 파일 끝에 도달하면 매치가 실패해요.
pattern 에서 input-prefix 가 #"" 이라고 가정할 때, 문자열-시작 ^ 은 start-pos 이후의 input 의 첫 위치를 가리켜요. 입력-끝 $ 는 end-pos 번째 위치나(입력 포트의 경우) 파일 끝 중 먼저 오는 것을 가리켜요.
input-prefix 는 ^ 및 다른 look-behind 매칭의 목적으로 input 앞에 실질적으로 놓이는 바이트를 지정해요. 예를 들어 #"" 접두사는 ^ 이 스트림의 시작에서 매치된다는 의미이고, #"\n" input-prefix 는 줄-시작 ^ 은 입력의 시작에서 매치될 수 있지만 파일-시작 ^ 은 그럴 수 없다는 뜻이에요.
매치가 실패하면 #f 가 반환돼요. 매치가 성공하면 문자열이나 바이트 문자열, 그리고 어쩌면 #f 를 포함하는 리스트가 반환돼요. 리스트는 input 이 문자열이고 pattern 이 바이트 regexp가 아닐 때만 문자열을 포함해요. 그렇지 않으면 리스트는 바이트 문자열(input 이 문자열이면 input 의 UTF-8 인코딩의 부분 문자열)을 포함해요.
결과 리스트의 첫 (바이트) 문자열은 pattern 과 매치된 input 의 부분이에요. input 의 두 부분이 pattern 과 매치될 수 있다면, 가장 먼저 시작하는 매치가 발견돼요.
pattern 이 괄호로 묶인 하위 표현식을 포함하면(여는 괄호 뒤에 ? 가 오는 경우 제외) 추가 (바이트) 문자열이 리스트에 반환돼요. 하위 표현식에 대한 매치는 pattern 의 여는 괄호 순서대로 제공돼요. 하위 표현식이 | "또는" 패턴의 분기, * "0회 이상" 패턴, 또는 전체 패턴이 하위 표현식의 매치 없이 성공할 수 있는 다른 자리에 나타나면, 하위 표현식이 최종 매치에 기여하지 않았다면 그 하위 표현식에 대해 #f 가 반환돼요. 단일 하위 표현식이 * "0회 이상" 패턴 안이나 다른 다중-매치 위치에 나타나면, 하위 표현식과 연관된 가장 오른쪽 매치가 리스트에 반환돼요.
선택적 output-port 가 출력 포트로 제공되면, 매치 앞에 오는 input 의 시작(이지 start-pos)부터의 부분이 포트에 쓰여져요. 매치가 발견되지 않으면 end-pos 까지의 input 전체가 포트에 쓰여져요. 이 기능은 input 이 입력 포트일 때 가장 유용해요.
입력 포트를 매칭할 때, pattern 이 문자열-시작 ^ 으로 시작해도 매치 실패는 end-pos 바이트(또는 파일 끝)까지 읽어요. regexp-try-match 도 참고해요. 성공 시, 매치를 포함한 모든 바이트가 결국 포트에서 읽히지만, 매칭은 먼저 포트에서 바이트를 peek(peek-bytes-avail! 사용)하고, 매치 결과가 결정된 후 매치 바이트를 (다시) 읽어 버림으로써 진행돼요. 매치가 결정되기 전에 매치되지 않는 바이트가 읽혀 버려질 수 있어요. 매처는 매치를 결정하는 데 필요한 만큼만 블로킹 모드로 peek하지만, 즉시 사용 가능하다면(즉 블로킹 없이) 내부 버퍼를 채우기 위해 추가 바이트를 peek할 수도 있어요. pattern 의 탐욕적 반복 연산자(* 나 + 등)는 매치를 결정하기 위해 포트의 전체 내용(end-pos 까지)을 읽도록 강제하는 경향이 있어요.
입력 포트가 다른 스레드에 의해 동시에 읽히거나, 일관되지 않은 읽기·peek 프로시저를 가진 커스텀 포트(Custom Ports 참고)라면, peek되어 매칭에 사용된 바이트가 매치 완료 후 읽혀 버려지는 바이트와 다를 수 있어요. 매처는 peek된 바이트만 검사해요. 그런 인터리빙을 피하려면 regexp-match-peek(progress 인자와 함께)을 사용한 뒤 port-commit-peeked 를 사용해요.
예:
> (regexp-match #rx"x." "12x4x6")
'("x4")
> (regexp-match #rx"y." "12x4x6")
#f
> (regexp-match #rx"x." "12x4x6" 3)
'("x6")
> (regexp-match #rx"x." "12x4x6" 3 4)
#f
> (regexp-match #rx#"x." "12x4x6")
'(#"x4")
> (regexp-match #rx"x." "12x4x6" 0 #f (current-output-port))
12
'("x4")
> (regexp-match #rx"(-[0-9]*)+" "a-12--345b")
'("-12--345" "-345")
procedure
(regexp-match* pattern input [start-pos end-pos input-prefix
#:match-select match-select
#:gap-select? gap-select])
→
(if (and (or (string? pattern) (regexp? pattern))
(or (string? input) (path? input)))
(listof (or/c string? (listof (or/c #f string?))))
(listof (or/c bytes? (listof (or/c #f bytes?)))))
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
input-prefix : bytes? = #""
match-select :
(or/c (list? . -> . (or/c any/c list?))
#f)
= car
gap-select : any/c = #f
regexp-match 와 같지만, 결과가 input 안의 pattern 매치 시퀀스에 해당하는 문자열이나 바이트 문자열의 리스트예요.
pattern 은 순서대로 매치를 찾는 데 사용되는데, 각 매치 시도는 마지막 매치의 끝에서 시작하고, ^ 은(만약 input-prefix 가 #"" 면) 첫 매치에 대해서만 입력의 시작과 매치될 수 있어요. 빈 매치는 다른 매치처럼 처리되어 길이가 0인 문자열이나 바이트 시퀀스를 반환해요(이것은 regexp-split 의 보수로 만드는 데 더 유용해요). 단, pattern 은 빈 매치 직후에 빈 시퀀스와 매치하는 것이 제한돼요.
input 이(start-pos 에서 end-pos 범위에) 매치를 포함하지 않으면 null 이 반환돼요. 그렇지 않으면 결과 리스트의 각 항목은 pattern 과 매치되는 input 의 서로 다른 부분 문자열이나 바이트 시퀀스예요. end-pos 인자는 #f 일 수 있어 input 의 끝까지 매치해요(input 이 입력 포트이면 파일 끝에 해당).
예:
> (regexp-match* #rx"x." "12x4x6")
'("x4" "x6")
> (regexp-match* #rx"x*" "12x4x6")
'("" "" "x" "" "x" "" "")
match-select 함수는 수집된 결과를 지정해요. 기본값 car 는 괄호로 묶인 하위 패턴을 반환하지 않고 매치 리스트가 결과라는 뜻이에요. 리스트에서 항목을 선택하는 "선택자" 함수로 주어질 수도 있고, 항목들의 리스트를 선택할 수도 있어요. 예를 들어 cdr 을 사용해 괄호로 묶인 하위 패턴 매치들의 리스트의 리스트를 얻거나, values(항등 함수로)를 사용해 전체 매치도 얻을 수 있어요. (선택자는 입력 리스트의 요소나 요소들의 리스트를 선택해야 하지만, 입력이 문자열 리스트 또는 위치 쌍 리스트일 수 있으므로 입력을 검사해선 안 되고, 선택자도 선택에서 일관적이어야 해요.)
예:
> (regexp-match* #rx"x(.)" "12x4x6" #:match-select cadr)
'("4" "6")
> (regexp-match* #rx"x(.)" "12x4x6" #:match-select values)
'(("x4" "4") ("x6" "6"))
추가로 gap-select 를 #f 가 아닌 값으로 지정하면 결과가 매치들과 그것들 사이의 구분자 매치들이 인터리브된 리스트가 되고, 구분자로 시작하고 끝나요. 이 경우 match-select 를 #f 로 주어 구분자만 반환하게 할 수 있고, 그런 사용은 regexp-split 과 동등해져요.
예:
> (regexp-match* #rx"x(.)" "12x4x6" #:match-select cadr #:gap-select? #t)
'("12" "4" "" "6" "")
> (regexp-match* #rx"x(.)" "12x4x6" #:match-select #f #:gap-select? #t)
'("12" "" "")
procedure
(regexp-try-match pattern input [start-pos end-pos output-port input-prefix])
→ (or/c #f (cons/c bytes? (listof (or/c bytes? #f))))
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
output-port : (or/c output-port? #f) = #f
input-prefix : bytes? = #""
입력 포트에서의 regexp-match 와 같지만, 매치가 실패하면 in 에서 읽히고 버려지는 문자가 없어요.
이 프로시저는 특히 문자열-시작 ^ 으로 시작하거나 #f 가 아닌 end-pos 를 가진 pattern 과 함께 유용한데, 둘 다 포트로의 peek 양을 제한하기 때문이에요. 그렇지 않으면 매치가 성공하거나 실패하기 전에 스트림의 큰 부분이 peek될(따라서 메모리로 끌려 들어올) 수 있음에 주의하세요.
procedure
(regexp-match-positions pattern input
[start-pos end-pos output-port input-prefix])
→
(or/c (cons/c (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?)
(listof (or/c (cons/c exact-integer?
exact-integer?)
#f)))
#f)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
output-port : (or/c output-port? #f) = #f
input-prefix : bytes? = #""
regexp-match 와 같지만, 문자열 리스트 대신 숫자 쌍(및 #f)의 리스트를 반환해요. 각 숫자 쌍은 input 의 문자나 바이트 범위를 가리켜요. 같은 인자에 대한 regexp-match 의 결과가 바이트 문자열 리스트였다면, 결과 범위는 바이트 범위에 해당해요. 이 경우 input 이 문자 문자열이면 바이트 범위는 문자열의 UTF-8 인코딩의 바이트에 해당해요.
범위 결과는 start-pos 와 무관하게 substring 및 subbytes 호환 방식으로 반환돼요. 입력 포트의 경우, 반환된 위치는 첫 매치 바이트 앞에 읽힌 바이트 수(start-pos 포함)를 나타내요.
예:
> (regexp-match-positions #rx"x." "12x4x6")
'((2 . 4))
> (regexp-match-positions #rx"x." "12x4x6" 3)
'((4 . 6))
> (regexp-match-positions #rx"(-[0-9]*)+" "a-12--345b")
'((1 . 9) (5 . 9))
input-prefix 가 비어 있지 않고 pattern 이 lookbehind 패턴을 포함하면 첫 이후의 범위 결과는 음수를 포함할 수 있어요. 그런 범위는 input 대신 input-prefix 에서 시작해요. 더 일반적으로 start-pos 가 양수이면, start-pos 보다 작은 범위 결과는 input-prefix 에서 시작해요.
예:
> (regexp-match-positions #rx"(?<=(.))." "a" 0 #f #f #"x")
'((0 . 1) (-1 . 0))
> (regexp-match-positions #rx"(?<=(..))." "a" 0 #f #f #"x")
#f
> (regexp-match-positions #rx"(?<=(..))." "_a" 1 #f #f #"x")
#f
input-prefix 는 항상 바이트 문자열이지만, 반환된 위치가 문자열 인덱스이고 input-prefix 의 일부를 가리키면, 그것들은 input-prefix 꼬리의 UTF-8 디코딩에 해당해요.
예:
> (bytes-length (string->bytes/utf-8 "λ"))
2
> (regexp-match-positions #rx"(?<=(.))." "a" 0 #f #f (string->bytes/utf-8 "λ"))
'((0 . 1) (-1 . 0))
procedure
(regexp-match-positions* pattern input
[start-pos end-pos input-prefix
#:match-select match-select])
→
(or/c (listof (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?))
(listof (listof (or/c #f (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?)))))
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
input-prefix : bytes? = #""
match-select : (list? . -> . (or/c any/c list?)) = car
regexp-match-positions 와 같지만, regexp-match* 처럼 여러 매치를 반환해요.
예:
> (regexp-match-positions* #rx"x." "12x4x6")
'((2 . 4) (4 . 6))
> (regexp-match-positions* #rx"x(.)" "12x4x6" #:match-select cadr)
'((3 . 4) (5 . 6))
regexp-match* 와 달리 #:gap-select? 입력 키워드가 없다는 점에 주의하세요. 이 정보는 결과 매치에서 쉽게 추론될 수 있기 때문이에요.
procedure
(regexp-match? pattern input [start-pos end-pos output-port input-prefix]) → boolean?
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
output-port : (or/c output-port? #f) = #f
input-prefix : bytes? = #""
regexp-match 와 같지만, 매치가 성공하면 #t 만, 그렇지 않으면 #f 를 반환해요.
예:
> (regexp-match? #rx"x." "12x4x6")
#t
> (regexp-match? #rx"y." "12x4x6")
#f
procedure
(regexp-match-exact? pattern input) → boolean?
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path?)
regexp-match? 와 같지만, 첫 번째로 발견된 매치가 input 의 전체 내용에 대한 매치일 때만 #t 가 반환돼요.
예:
> (regexp-match-exact? #rx"x." "12x4x6")
#f
> (regexp-match-exact? #rx"1.*x." "12x4x6")
#t
regexp-match-exact? 는 pattern 이 input 에 대한 부분 매치를 먼저 만들면, pattern 이 완전한 매치도 만들 수 있어도 #f 를 반환할 수 있음에 주의하세요. input 전체를 덮는 pattern 의 매치가 있는지 확인하려면 regexp-match? 를 ^(?:pattern)$ 과 함께 사용해요.
예:
> (regexp-match-exact? #rx"a|ab" "ab")
#f
> (regexp-match? #rx"^(?:a|ab)$" "ab")
#t
(?:) 그룹핑이 필요한 이유는 연결(concatenation)이 선택(alternation)보다 우선순위가 낮기 때문이에요. 그룹핑이 없는 정규 표현식 ^a|ab$ 는 a 로 시작하거나 ab 로 끝나는 어떤 입력과도 매치돼요.
예:
> (regexp-match? #rx"^a|ab$" "123ab")
#t
procedure
(regexp-match-peek pattern input
[start-pos end-pos progress input-prefix])
→
(or/c (cons/c bytes? (listof (or/c bytes? #f)))
#f)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
progress : (or/c progress-evt? #f) = #f
input-prefix : bytes? = #""
입력 포트에서의 regexp-match 와 같지만, input 에서 바이트를 읽는 대신 peek만 해요. 게다가 출력 포트 대신 선택적 progress 인자는 input 의 진행 이벤트예요(port-progress-evt 참고). progress 가 준비되면 매치는 input 에서 peek을 멈추고 #f 를 반환해요. progress 인자는 #f 일 수 있는데, 이 경우 다른 프로세스가 그동안 input 에서 읽으면 peek이 일관되지 않은 정보로 계속될 수 있어요.
예:
> (define p (open-input-string "a abcd"))
> (regexp-match-peek ".*bc" p)
'(#"a abc")
> (regexp-match-peek ".*bc" p 2)
'(#"abc")
> (regexp-match ".*bc" p 2)
'(#"abc")
> (peek-char p)
#\d
> (regexp-match ".*bc" p)
#f
> (peek-char p)
#<eof>
procedure
(regexp-match-peek-positions pattern input
[start-pos end-pos progress input-prefix])
→
(or/c (cons/c (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?)
(listof (or/c (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?)
#f)))
#f)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
progress : (or/c progress-evt? #f) = #f
input-prefix : bytes? = #""
입력 포트에서의 regexp-match-positions 와 같지만, input 에서 바이트를 읽는 대신 peek만 하고, regexp-match-peek 처럼 progress 인자를 가져요.
procedure
(regexp-match-peek-immediate pattern input
[start-pos end-pos progress input-prefix])
→
(or/c (cons/c bytes? (listof (or/c bytes? #f)))
#f)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
progress : (or/c progress-evt? #f) = #f
input-prefix : bytes? = #""
regexp-match-peek 와 같지만, input 에서 블로킹 없이 사용 가능한 바이트에만 매치를 시도해요. 아직 사용할 수 없는 문자가 pattern 을 매치하는 데 사용될 수 있다면 매치는 실패해요.
procedure
(regexp-match-peek-positions-immediate pattern input
[start-pos end-pos progress input-prefix])
→
(or/c (cons/c (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?)
(listof (or/c (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?)
#f)))
#f)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
progress : (or/c progress-evt? #f) = #f
input-prefix : bytes? = #""
regexp-match-peek-positions 와 같지만, input 에서 블로킹 없이 사용 가능한 바이트에만 매치를 시도해요. 아직 사용할 수 없는 문자가 pattern 을 매치하는 데 사용될 수 있다면 매치는 실패해요.
procedure
(regexp-match-peek-positions* pattern input
[start-pos end-pos input-prefix
#:match-select match-select])
→
(or/c (listof (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?))
(listof (listof (or/c #f (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?)))))
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
input-prefix : bytes? = #""
match-select : (list? . -> . (or/c any/c list?)) = car
regexp-match-peek-positions 와 같지만, regexp-match-positions* 처럼 여러 매치를 반환해요.
procedure
(regexp-match/end pattern input
[start-pos end-pos output-port input-prefix count])
→
(if (and (or (string? pattern) (regexp? pattern))
(or/c (string? input) (path? input)))
(or/c #f (cons/c string? (listof (or/c string? #f))))
(or/c #f (cons/c bytes? (listof (or/c bytes? #f)))))
(or/c #f bytes?)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
output-port : (or/c output-port? #f) = #f
input-prefix : bytes? = #""
count : exact-nonnegative-integer? = 1
regexp-match 와 같지만, 두 번째 결과가 있어요: 매치의 끝으로 이어지는 입력(input-prefix 를 포함할 수 있음)에 해당하는 최대 count 바이트의 바이트 문자열이에요. 매치가 없으면 두 번째 결과는 #f 예요.
두 번째 결과는 첫 매치의 끝에서 시작하는 input 에 대한 두 번째 매치를 시도할 때 input-prefix 로 유용할 수 있어요. 그 경우 regexp-max-lookbehind 를 사용해 count 의 적절한 값을 결정해요.
procedure
(regexp-match-positions/end pattern input
[start-pos end-pos input-prefix count])
→
(listof (cons/c exact-nonnegative-integer?
exact-nonnegative-integer?))
(or/c #f bytes?)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? path? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
input-prefix : bytes? = #""
count : exact-nonnegative-integer? = 1
procedure
(regexp-match-peek-positions/end pattern input
[start-pos end-pos progress input-prefix count]) → (or/c (cons/c (cons/c exact-nonnegative-integer? exact-nonnegative-integer?) (listof (or/c (cons/c exact-nonnegative-integer? exact-nonnegative-integer?) #f))) #f)
(or/c #f bytes?)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
progress : (or/c progress-evt? #f) = #f
input-prefix : bytes? = #""
count : exact-nonnegative-integer? = 1
procedure
(regexp-match-peek-positions-immediate/end pattern input
[start-pos end-pos progress input-prefix count]) → (or/c (cons/c (cons/c exact-nonnegative-integer? exact-nonnegative-integer?) (listof (or/c (cons/c exact-nonnegative-integer? exact-nonnegative-integer?) #f))) #f)
(or/c #f bytes?)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : input-port?
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
progress : (or/c progress-evt? #f) = #f
input-prefix : bytes? = #""
count : exact-nonnegative-integer? = 1
regexp-match-positions 등과 같지만, regexp-match/end 처럼 두 번째 결과가 있어요.
4.8.5 Regexp 분할
procedure
(regexp-split pattern input [start-pos end-pos input-prefix])
→
(if (and (or (string? pattern) (regexp? pattern))
(string? input))
(cons/c string? (listof string?))
(cons/c bytes? (listof bytes?)))
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes? input-port?)
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
input-prefix : bytes? = #""
regexp-match* 의 보수예요. 결과는 pattern 과의 매치로 구분되는 input 의 문자열(pattern 이 문자열이거나 문자 regexp이고 input 이 문자열일 때) 또는 바이트 문자열(그 외)의 리스트예요. 인접한 매치는 "" 나 #"" 로 구분돼요. 길이가 0인 매치는 regexp-match* 와 같게 처리돼요.
input 이(start-pos 에서 end-pos 범위에) 매치를 포함하지 않으면, 결과는 input 의 내용(start-pos 에서 end-pos 까지)을 단일 요소로 포함하는 리스트예요. 매치가 input 의 시작(start-pos)에서 발생하면 결과 리스트는 빈 문자열이나 빈 바이트 문자열로 시작하고, 매치가 끝(end-pos)에서 발생하면 리스트는 빈 문자열이나 빈 바이트 문자열로 끝나요. end-pos 인자는 #f 일 수 있어서 분할이 input 의 끝까지 진행돼요(input 이 입력 포트이면 파일 끝에 해당).
예:
> (regexp-split #rx" +" "12 34")
'("12" "34")
> (regexp-split #rx"." "12 34")
'("" "" "" "" "" "" "")
> (regexp-split #rx"" "12 34")
'("" "1" "2" " " " " "3" "4" "")
> (regexp-split #rx" *" "12 34")
'("" "1" "2" "" "3" "4" "")
> (regexp-split #px"\\b" "12, 13 and 14.")
'("" "12" ", " "13" " " "and" " " "14" ".")
> (regexp-split #rx" +" "")
'("")
4.8.6 Regexp 치환
procedure
(regexp-replace pattern input insert [input-prefix])
→
(if (and (or (string? pattern) (regexp? pattern))
(string? input))
string?
bytes?)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes?)
insert :
(or/c string? bytes?
(string? string? ... . -> . string?)
(bytes? bytes? ... . -> . bytes?))
input-prefix : bytes? = #""
pattern 으로 input 에서 매치를 수행한 다음, input 의 매치 부분이 insert 로 대체된 문자열이나 바이트 문자열을 반환해요. pattern 이 input 의 어떤 부분과도 매치하지 않으면 input 이 수정 없이 반환돼요.
insert 인자는 (바이트) 문자열이거나 (바이트) 문자열을 반환하는 함수일 수 있어요. 후자의 경우, 함수는 regexp-match 가 반환할 값들의 리스트에 적용돼요(즉, 첫 인자는 완전한 매치이고, 그다음 괄호로 묶인 각 하위 표현식에 대해 하나씩) 대체 (바이트) 문자열을 얻어요.
pattern 이 문자열이거나 문자 regexp이고 input 이 문자열이면, insert 는 문자열이거나 문자열을 받는 프로시저여야 하고 결과는 문자열이에요. pattern 이 바이트 문자열이거나 바이트 regexp이거나 input 이 바이트 문자열이면, 문자열로서의 insert 는 바이트 문자열로 변환되고, 프로시저로서의 insert 는 바이트 문자열로 호출되며, 결과는 바이트 문자열이에요.
insert 가 & 를 포함하면, & 는 매치 자리에 대입되기 전에 input 의 매치 부분으로 대체돼요. insert 가 어떤 정수 ‹n› 에 대해 \‹n› 을 포함하면, input 의 ‹n›번째 매치 하위 표현식으로 대체돼요. & 와 \0 은 별칭이에요. ‹n›번째 하위 표현식이 매치에 사용되지 않았거나, ‹n› 이 pattern 의 하위 표현식 수보다 크면 \‹n› 은 빈 문자열로 대체돼요.
리터럴 & 나 \ 를 대체하려면 insert 에서 각각 \& 와 \\ 를 사용해요. insert 의 \$ 는 빈 시퀀스와 동등해요. 이것은 \ 다음의 숫자 ‹n› 을 종료하는 데 사용될 수 있어요. insert 의 \ 뒤에 숫자, &, \, $ 가 아닌 다른 것이 오면, 그 \ 자체가 \0 으로 취급돼요.
앞 단락에서 설명한 \ 는 insert 의 문자나 바이트라는 점에 주의하세요. 그런 insert 를 Racket 문자열 리터럴로 쓰려면 \ 앞에 이스케이프 \ 가 필요해요. 예를 들어 Racket 상수 "\\1" 은 \1 이에요.
예:
> (regexp-replace #rx"([Mm])i ([a-zA-Z]*)" "mi cerveza Mi Mi Mi"
"\\1y \\2")
"my cerveza Mi Mi Mi"
(regexp-replace #rx"x" "12x4x6" "\\\\")
"12\\4x6"
(display (regexp-replace #rx"x" "12x4x6" "\\\\"))
12\4x6
procedure
(regexp-replace* pattern input insert [start-pos end-pos input-prefix]) → (or/c string? bytes?)
pattern : (or/c regexp? byte-regexp? string? bytes?)
input : (or/c string? bytes?)
insert :
(or/c string? bytes?
(string? string? ... . -> . string?)
(bytes? bytes? ... . -> . bytes?))
start-pos : exact-nonnegative-integer? = 0
end-pos : (or/c exact-nonnegative-integer? #f) = #f
input-prefix : bytes? = #""
regexp-replace 와 같지만, input 의 pattern 인스턴스마다 insert 로 대체돼요(첫 매치 대신). 결과는 매치가 없고 start-pos 가 0 이며 end-pos 가 #f 이거나 input 의 길이일 때만 input 그대로예요. input 에서 겹치지 않는 pattern 인스턴스만 대체되므로, 삽입된 문자열 안의 pattern 인스턴스는 재귀적으로 대체되지 않아요. 길이가 0인 매치는 regexp-match* 와 같게 처리돼요.
선택적 start-pos 와 end-pos 인자는 매칭할 input 의 일부를 선택해요. 기본값은 전체 문자열 또는 파일 끝까지의 스트림이에요.
예:
> (regexp-replace* #rx"([Mm])i ([a-zA-Z]*)" "mi cerveza Mi Mi Mi"
"\\1y \\2")
"my cerveza My Mi Mi"
> (regexp-replace* #rx"([Mm])i ([a-zA-Z]*)" "mi cerveza Mi Mi Mi"
(lambda (all one two)
(string-append (string-downcase one) "y"
(string-upcase two))))
"myCERVEZA myMI Mi"
(regexp-replace* #px"\\w" "hello world" string-upcase 0 5)
"HELLO world"
(display (regexp-replace* #rx"x" "12x4x6" "\\\\"))
12\4\6
Changed in version 8.1.0.7 of package base: 치환이 수행되지 않을 때 input 을 반환하도록 변경됐어요.
(listof
(list/c (or/c regexp? byte-regexp? string? bytes?)
(or/c string? bytes?
(string? string? ... . -> . string?)
(bytes? bytes? ... . -> . bytes?))))
procedure
(regexp-replaces input replacements) → (or/c string? bytes?)
input : (or/c string? bytes?)
replacements :
regexp-replace* 연산의 체인을 수행해요. replacements 의 각 요소는 (list pattern insert) 로 대체를 지정해요. 대체는 순서대로 수행되므로, 나중 대체는 이전 삽입에 적용될 수 있어요.
예:
> (regexp-replaces "zero-or-more?"
'([#rx"-" "_"] [#rx"(.*)\\?$" "is_\\1"]))
"is_zero_or_more"
> (regexp-replaces "zero-or-more?"
'([#rx"e" "o"] [#rx"o" "oo"]))
"zooroo-oor-mooroo?"
procedure
(regexp-replace-quote str) → string?
str : string?
(regexp-replace-quote bstr) → bytes?
bstr : bytes?
str 의 리터럴 문자 시퀀스나 bstr 의 바이트를 대체로 삽입하기 위해 regexp-replace 의 세 번째 인자로 쓰기에 적합한 문자열을 만들어요. 구체적으로 str 이나 bstr 의 모든 \ 와 & 가 인용 \ 로 보호돼요.
예:
> (regexp-replace #rx"UT" "Go UT!" "A&M")
"Go AUTM!"
> (regexp-replace #rx"UT" "Go UT!" (regexp-replace-quote "A&M"))
"Go A&M!"