문자열

문자열 (Strings)

문자열은 문자들의 고정 길이 배열입니다. 문자열은 가변이거나 불변일 수 있고, 단일 값 시퀀스로도 사용될 수 있습니다. 문자열을 만들고, 비교하고, 변환하고, 포맷하는 다양한 함수들을 다룹니다.

출처: Racket Reference

본문

Racket Guide의 Strings (Unicode)에서 문자열을 소개합니다.

문자열은 문자들의 고정 길이 배열입니다.

문자열은 가변이거나 불변일 수 있습니다. 불변 문자열이 string-set! 같은 절차에 제공되면 exn:fail:contract 예외가 발생합니다. 기본 판독기(Reading Strings 참고)가 생성한 문자열 상수는 불변이며, read-syntax 모드에서는 내부화(interned)됩니다. 문자열이 불변인지 확인하려면 immutable?를 사용하세요.

두 문자열은 같은 길이를 갖고 같은 문자 수열을 포함할 때 서로 equal?입니다.

문자열은 단일 값 시퀀스로 사용될 수 있습니다(Sequences 참고). 문자열의 문자들이 시퀀스의 요소 역할을 합니다. in-string도 참고하세요.

문자열 읽기에 대한 정보는 Reading Strings를, 문자열 출력에 대한 정보는 Printing Strings를 참고하세요.

다음도 참고하세요: immutable?, symbol->string, bytes->string/utf-8.

String Constructors, Selectors, and Mutators

procedure

(string? v) → boolean?
  v : any/c

v가 문자열이면 #t를, 그렇지 않으면 #f를 반환합니다.

immutable-string?mutable-string?도 참고하세요.

예시:

> (string? "Apple")

#t
> (string? 'apple)

#f

procedure

(make-string k [char]) → string?
  k : exact-nonnegative-integer?
  char : char? = #\nul

길이 k이고 각 위치가 문자 char로 초기화된 새 가변 문자열을 반환합니다.

예시:

> (make-string 5 #\z)

"zzzzz"

procedure

(string char ...) → string?
  char : char?

길이가 제공된 char 수이고 위치들이 주어진 char들로 초기화된 새 가변 문자열을 반환합니다.

예시:

> (string #\A #\p #\p #\l #\e)

"Apple"

procedure

(string->immutable-string str) → (and/c string? immutable?)
  str : string?

str과 같은 내용을 가진 불변 문자열을 반환합니다. str이 불변이면 str 자체를 반환합니다.

예시:

> (immutable? (string #\H #\e #\l #\l #\o))

#f
> (immutable? (string->immutable-string (string #\H #\e #\l #\l #\o)))

#t

procedure

(string-length str) → exact-nonnegative-integer?
  str : string?

str의 길이를 반환합니다.

예시:

> (string-length "Apple")

5

procedure

(string-ref str k) → char?
  str : string?
  k : exact-nonnegative-integer?

str의 위치 k에 있는 문자를 반환합니다. 문자열의 첫 번째 위치는 0에 해당하므로, 위치 k는 문자열 길이보다 작아야 합니다. 그렇지 않으면 exn:fail:contract 예외가 발생합니다.

예시:

> (string-ref "Apple" 0)

#\A

procedure

(string-set! str k char) → void?
  str : (and/c string? (not/c immutable?))
  k : exact-nonnegative-integer?
  char : char?

str의 문자 위치 kchar로 바꿉니다. 문자열의 첫 번째 위치는 0에 해당하므로, 위치 k는 문자열 길이보다 작아야 합니다. 그렇지 않으면 exn:fail:contract 예외가 발생합니다.

예시:

> (define s (string #\A #\p #\p #\l #\e))
> (string-set! s 4 #\y)
> s

"Apply"

procedure

(substring str start [end]) → string?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (string-length str)

길이가 (- end start) 문자이고, str에서 start 포함부터 end 제외까지의 같은 문자들을 포함하는 새 가변 문자열을 반환합니다. 문자열의 첫 번째 위치는 0에 해당하므로, startend 인자는 str의 길이보다 작거나 같아야 하고, endstart보다 크거나 같아야 합니다. 그렇지 않으면 exn:fail:contract 예외가 발생합니다.

예시:

> (substring "Apple" 1 3)

"pp"
> (substring "Apple" 1)

"pple"

procedure

(string-copy str) → string?
  str : string?

(substring str 0)을 반환합니다.

예시:

> (define s1 "Yui")
> (define pilot (string-copy s1))
> (list s1 pilot)

'("Yui" "Yui")
> (for ([i (in-naturals)] [ch '(#\R #\e #\i)])
    (string-set! pilot i ch))

> (list s1 pilot)

'("Yui" "Rei")

procedure

(string-copy! dest
  dest-start
  src
  [src-start
  src-end]) → void?

  dest : (and/c string? (not/c immutable?))
  dest-start : exact-nonnegative-integer?
  src : string?
  src-start : exact-nonnegative-integer? = 0
  src-end : exact-nonnegative-integer? = (string-length src)

위치 dest-start에서 시작하는 dest의 문자들을, src-start(포함)부터 src-end(제외)까지의 src의 문자들과 일치하도록 바꿉니다. 여기서 문자열의 첫 번째 위치는 0에 해당합니다. 문자열 destsrc는 같은 문자열일 수 있으며, 그 경우 대상 영역이 원본 영역과 겹칠 수 있습니다. 복사 후의 대상 문자들은 복사 전의 원본 문자들과 일치합니다. dest-start, src-start, src-end 중 어떤 것이(문자열 크기와 원본/대상 영역을 고려해) 범위를 벗어나면 exn:fail:contract 예외가 발생합니다.

예시:

> (define s (string #\A #\p #\p #\l #\e))
> (string-copy! s 4 "y")
> (string-copy! s 0 s 3 4)
> s

"lpply"

procedure

(string-fill! dest char) → void?
  dest : (and/c string? (not/c immutable?))
  char : char?

dest를 문자열의 모든 위치가 char로 채워지도록 바꿉니다.

예시:

> (define s (string #\A #\p #\p #\l #\e))
> (string-fill! s #\q)
> s

"qqqqq"

procedure

(string-append str ...) → string?
  str : string?

주어진 str들의 길이의 합만큼 길고, 주어진 str들의 이어붙여진 문자들을 포함하는 새 가변 문자열을 반환합니다. str이 제공되지 않으면 결과는 길이 0인 문자열입니다.

예시:

> (string-append "Apple" "Banana")

"AppleBanana"

procedure

(string-append-immutable str ...) → (and/c string? immutable?)
  str : string?

string-append와 같지만, 결과가 불변 문자열입니다.

예시:

> (string-append-immutable "Apple" "Banana")

"AppleBanana"
> (immutable? (string-append-immutable "A" "B"))

#t

base 패키지의 7.5.0.14 버전에서 추가되었습니다.

procedure

(string->list str) → (listof char?)
  str : string?

str의 내용에 해당하는 문자들의 새 리스트를 반환합니다. 즉 리스트의 길이는 (string-length str)이고, str의 문자 수열은 결과 리스트에서도 같은 수열입니다.

예시:

> (string->list "Apple")

'(#\A #\p #\p #\l #\e)

procedure

(list->string lst) → string?
  lst : (listof char?)

내용이 lst의 문자 리스트인 새 가변 문자열을 반환합니다. 즉 문자열의 길이는 (length lst)이고, lst의 문자 수열은 결과 문자열에서도 같은 수열입니다.

예시:

> (list->string (list #\A #\p #\p #\l #\e))

"Apple"

procedure

(build-string n proc) → string?
  n : exact-nonnegative-integer?
  proc : (exact-nonnegative-integer? . -> . char?)

0부터 (sub1 n)까지의 정수들에 proc을 순서대로 적용해 n개 문자의 문자열을 만듭니다. str이 결과 문자열이면, (string-ref str i)(proc i)가 만들어낸 문자입니다.

예시:

> (build-string 5 (lambda (i) (integer->char (+ i 97))))

"abcde"

String Comparisons

procedure

(string=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

모든 인자들이 equal?이면 #t를 반환합니다.

예시:

> (string=? "Apple" "apple")

#f
> (string=? "a" "as" "a")

#f

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string<? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

인자들이 사전순으로 오름차순 정렬되어 있으면 #t를, 그렇지 않으면 #f를 반환합니다. 개별 문자들은 char<?로 정렬됩니다.

예시:

> (string<? "Apple" "apple")

#t
> (string<? "apple" "Apple")

#f
> (string<? "a" "b" "c")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string<=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string<?와 같지만, 인자들이 비감소(nondecreasing)인지 검사합니다.

예시:

> (string<=? "Apple" "apple")

#t
> (string<=? "apple" "Apple")

#f
> (string<=? "a" "b" "b")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string>? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string<?와 같지만, 인자들이 감소(decreasing)인지 검사합니다.

예시:

> (string>? "Apple" "apple")

#f
> (string>? "apple" "Apple")

#t
> (string>? "c" "b" "a")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string>=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string<?와 같지만, 인자들이 비증가(nonincreasing)인지 검사합니다.

예시:

> (string>=? "Apple" "apple")

#f
> (string>=? "apple" "Apple")

#t
> (string>=? "c" "b" "b")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-ci=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string-foldcase를 통한 로케일 무관 대소문자 접기(case-folding) 후 모든 인자들이 equal?이면 #t를 반환합니다.

예시:

> (string-ci=? "Apple" "apple")

#t
> (string-ci=? "a" "a" "a")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-ci<? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string<?와 같지만, 각각이 먼저 string-foldcase(로케일 무관)로 대소문자 접기되면 인자들이 오름차순일지 검사합니다.

예시:

> (string-ci<? "Apple" "apple")

#f
> (string-ci<? "apple" "banana")

#t
> (string-ci<? "a" "b" "c")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-ci<=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string-ci<?와 같지만, 대소문자 접기 후 인자들이 비감소일지 검사합니다.

예시:

> (string-ci<=? "Apple" "apple")

#t
> (string-ci<=? "apple" "Apple")

#t
> (string-ci<=? "a" "b" "b")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-ci>? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string-ci<?와 같지만, 대소문자 접기 후 인자들이 감소일지 검사합니다.

예시:

> (string-ci>? "Apple" "apple")

#f
> (string-ci>? "banana" "Apple")

#t
> (string-ci>? "c" "b" "a")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-ci>=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string-ci<?와 같지만, 대소문자 접기 후 인자들이 비증가일지 검사합니다.

예시:

> (string-ci>=? "Apple" "apple")

#t
> (string-ci>=? "apple" "Apple")

#t
> (string-ci>=? "c" "b" "b")

#t

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

String Conversions

procedure

(string-upcase str) → string?
  str : string?

문자들이 str의 문자들의 대문자 변환인 문자열을 반환합니다. 변환은 코드-포인트 수열을 코드-포인트 수열로 매핑하는(문자열에 대해 코드 포인트의 단순한 1:1 함수를 매핑하는 대신) 유니코드의 로케일 독립적 변환 규칙을 사용하므로, 변환이 만들어내는 문자열은 입력 문자열보다 길 수 있습니다.

예시:

> (string-upcase "abc!")

"ABC!"
> (string-upcase "Straße")

"STRASSE"

procedure

(string-downcase string) → string?
  string : string?

string-upcase와 같지만, 소문자 변환입니다.

예시:

> (string-downcase "aBC!")

"abc!"
> (string-downcase "Straße")

"straße"
> (string-downcase "ΚΑΟΣ")

"καος"
> (string-downcase "Σ")

"σ"

procedure

(string-titlecase string) → string?
  string : string?

string-upcase와 같지만, str의 각 대소문자 구분 문자(cased character) 수열에서 첫 번째 문자에 대해서만 titlecase 변환을 합니다(대소문자 무시 문자(case-ignorable characters)는 무시).

예시:

> (string-titlecase "aBC  twO")

"Abc  Two"
> (string-titlecase "y2k")

"Y2k"
> (string-titlecase "main straße")

"Main Straße"
> (string-titlecase "stra ße")

"Stra Sse"

procedure

(string-foldcase string) → string?
  string : string?

string-upcase와 같지만, 대소문자 접기(case-folding) 변환입니다.

예시:

> (string-foldcase "aBC!")

"abc!"
> (string-foldcase "Straße")

"strasse"
> (string-foldcase "ΚΑΟΣ")

"καοσ"

procedure

(string-normalize-nfd string) → string?
  string : string?

string의 유니코드 정규화 형식 D인 문자열을 반환합니다. 주어진 문자열이 이미 대응하는 유니코드 정규 형식이면, (새로 할당된 문자열 대신) 그 문자열이 직접 결과로 반환될 수 있습니다.

예시:

> (equal? (string-normalize-nfd "Ç") "Ç")

#t

procedure

(string-normalize-nfkd string) → string?
  string : string?

string-normalize-nfd와 같지만, 정규화 형식 KD에 대한 것입니다.

예시:

> (equal? (string-normalize-nfkd "ℌ") "H")

#t

procedure

(string-normalize-nfc string) → string?
  string : string?

string-normalize-nfd와 같지만, 정규화 형식 C에 대한 것입니다.

예시:

> (equal? (string-normalize-nfc "Ç") "Ç")

#t

procedure

(string-normalize-nfkc string) → string?
  string : string?

string-normalize-nfd와 같지만, 정규화 형식 KC에 대한 것입니다.

예시:

> (equal? (string-normalize-nfkc "ℋ̧") "Ḩ")

#t

Locale-Specific String Operations

procedure

(string-locale=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string=?와 같지만, current-locale의 값에 기반해 로케일 특유 방식으로 문자열을 비교합니다. 로케일에 대한 자세한 정보는 Encodings and Locales를 참고하세요.

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-locale<? str1 str2 ...+) → boolean?
  str1 : string?
  str2 : string?

string<?와 같지만, current-locale의 값에 기반해 로케일 특유 방식으로 문자열을 비교합니다. 특히 정렬 순서가 단순히 문자 순서의 사전순 확장이 아닐 수도 있습니다.

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-locale>? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string>?와 같지만, string-locale<?처럼 로케일 특유입니다.

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-locale-ci=? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string-locale=?와 같지만, 로케일 특유이면서 대소문자 무관(현재 로케일에서 "대소문자 무관"이 의미하는 바에 따라)인 규칙으로 문자열을 비교합니다.

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-locale-ci<? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string<?와 같지만, string-locale-ci=?처럼 로케일 민감하고 대소문자 무관합니다.

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-locale-ci>? str1 str2 ...) → boolean?
  str1 : string?
  str2 : string?

string>?와 같지만, string-locale-ci=?처럼 로케일 민감하고 대소문자 무관합니다.

base 패키지의 7.0.0.13 버전에서 변경됨: 둘 이상을 허용하는 것 외에 인자 하나도 허용함.

procedure

(string-locale-upcase string) → string?
  string : string?

string-upcase와 같지만, current-locale의 값에 기반한 로케일 특유 대소문자 변환 규칙을 사용합니다.

procedure

(string-locale-downcase string) → string?
  string : string?

string-downcase와 같지만, current-locale의 값에 기반한 로케일 특유 대소문자 변환 규칙을 사용합니다.

String Grapheme Clusters

procedure

(string-grapheme-span str start [end]) → exact-nonnegative-integer?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (string-length str)

start에서 시작해 end 앞의 문자를 넘지 않는 유니코드 그래핌 클러스터(grapheme cluster)를 형성하는 str의 문자(즉 코드 포인트) 수를 반환합니다. start가 그래핌 클러스터의 시작이라고 가정합니다. startend와 같으면 결과는 0입니다.

startend 인자는 substring에서처럼 유효한 인덱스여야 합니다. 그렇지 않으면 exn:fail:contract 예외가 발생합니다.

char-grapheme-cluster-step도 참고하세요.

예시:

> (string-grapheme-span "" 0)

0
> (string-grapheme-span "a" 0)

1
> (string-grapheme-span "ab" 0)

1
> (string-grapheme-span "\r\n" 0)

2
> (string-grapheme-span "\r\nx" 0)

2
> (string-grapheme-span "\r\nx" 2)

1
> (string-grapheme-span "\r\nx" 0 1)

1

base 패키지의 8.6.0.2 버전에서 추가되었습니다.

procedure

(string-grapheme-count str start [end])
→ exact-nonnegative-integer?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (string-length str)

(substring str start end)의 그래핌 클러스터 수를 반환합니다.

startend 인자는 substring에서처럼 유효한 인덱스여야 합니다. 그렇지 않으면 exn:fail:contract 예외가 발생합니다.

예시:

> (string-grapheme-count "")

0
> (string-grapheme-count "a")

1
> (string-grapheme-count "ab")

2
> (string-grapheme-count "ab" 0 2)

2
> (string-grapheme-count "ab" 0 1)

1
> (string-grapheme-count "\r\n")

1
> (string-grapheme-count "a\r\nb")

3

base 패키지의 8.6.0.2 버전에서 추가되었습니다.

Additional String Functions

(require racket/string) ; package: base

이 섹션에 문서화된 바인딩은 racket/stringracket 라이브러리가 제공하지만, racket/base는 제공하지 않습니다.

procedure

(string-append* str ... strs) → string?
  str : string?
  strs : (listof string?)

string-append와 같지만, 마지막 인자가 string-append의 인자 리스트로 사용되므로, (string-append* str ... strs)(apply string-append str ... strs)와 같습니다. 다시 말해, string-appendstring-append*의 관계는 listlist*의 관계와 유사합니다.

예시:

> (string-append* "a" "b" '("c" "d"))

"abcd"
> (string-append* (cdr (append* (map (lambda (x) (list ", " x))
                                     '("Alpha" "Beta" "Gamma")))))

"Alpha, Beta, Gamma"

procedure

(string-join strs
  [sep
  #:before-first before-first
  #:before-last before-last
  #:after-last after-last]) → string?

  strs : (listof string?)
  sep : string? = " "
  before-first : string? = ""
  before-last : string? = sep
  after-last : string? = ""

strs의 문자열들을 추가하면서, strs의 각 문자열 쌍 사이에 sep을 삽입합니다. before-last, before-first, after-last는 각각 add-between의 입력과 유사합니다. 마지막 두 문자열 사이의 대체 구분 기호, 접두사 문자열, 접미사 문자열을 지정합니다.

예시:

> (string-join '("one" "two" "three" "four"))

"one two three four"
> (string-join '("one" "two" "three" "four") ", ")

"one, two, three, four"
> (string-join '("one" "two" "three" "four") " potato ")

"one potato two potato three potato four"
> (string-join '("x" "y" "z") ", "
               #:before-first "Todo: "
               #:before-last " and "
               #:after-last ".")

"Todo: x, y and z."

procedure

(string-normalize-spaces str
  [sep
  space
  #:trim? trim?
  #:repeat? repeat?]) → string?

  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  space : string? = " "
  trim? : any/c = #t
  repeat? : any/c = #f

(string-trimsep으로) 다듬고 결과의 모든 공백 수열을 space(기본은 단일 공백)로 대체해 입력 str의 공백을 정규화합니다.

예시:

> (string-normalize-spaces "  foo bar  baz \r\n\t")

"foo bar baz"

(string-normalize-spaces str sep space)의 결과는 (string-join (string-split str sep ....) space)와 같습니다.

procedure

(string-replace str from to [#:all? all?]) → string?
  str : string?
  from : (or/c string? regexp?)
  to : string?
  all? : any/c = #t

from의 모든 출현이 to로 대체된 str을 반환합니다. from이 문자열이면 (정규 표현식으로 사용되는 대신) 문자 그대로 매치됩니다.

기본적으로 모든 출현이 대체되지만, all?#f이면 첫 번째 매치만 대체됩니다.

예시:

> (string-replace "foo bar baz" "bar" "blah")

"foo blah baz"

procedure

(string-split str
  [sep
  #:trim? trim?
  #:repeat? repeat?]) → (listof string?)

  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  trim? : any/c = #t
  repeat? : any/c = #f

입력 strsep으로 분할해, sep으로 구분된 str의 부분 문자열 리스트를 반환합니다. 기본은 입력을 공백으로 분할하는 것입니다. trim?#f가 아니면 입력이 먼저 sep으로 다듬어집니다(string-trim 참고). 빈 매치는 regexp-split과 같은 방식으로 처리됩니다. 특수한 경우로, 다듬은 후 str이 빈 문자열이면 결과는 '("") 대신 '()입니다.

string-trim처럼 sep을 제공해 다른 구분 기호를 사용하고, repeat?는 반복된 수열의 매치를 제어합니다.

예시:

> (string-split "  foo bar  baz \r\n\t")

'("foo" "bar" "baz")
> (string-split "  ")

'()
> (string-split "  " #:trim? #f)

'("" "")

procedure

(string-trim str
  [sep
  #:left? left?
  #:right? right?
  #:repeat? repeat?]) → string?

  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  left? : any/c = #t
  right? : any/c = #t
  repeat? : any/c = #f

sep과 일치하는 접두사와 접미사를 제거해 입력 str을 다듬습니다. sep은 기본적으로 공백과 일치합니다. 문자열 sep은 (정규 표현식으로 사용되는 대신) 문자 그대로 매치됩니다.

#:left? #f 또는 #:right? #f를 사용해 해당 쪽의 다듬기를 억제하세요. repeat?#f(기본)이면 각 쪽에서 하나의 매치만 제거되고, repeat?가 참이면 모든 처음 또는 끝 매치가 다듬어집니다(이는 +를 포함한 정규 표현식 sep을 사용하는 것에 대한 대안입니다).

문자열의 왼쪽과 오른쪽 끝을 둘 다 다듬을 때, 두 매치 모두 원래 문자열에 대해 수행됩니다(먼저 왼쪽을 다듬고 그 다음 오른쪽을 다듬는 것과 반대). 왼쪽과 오른쪽 매치가 겹치면, 다듬어진 결과 문자열은 비어 있습니다.

예시:

> (string-trim "  foo bar  baz \r\n\t")

"foo bar  baz"
> (string-trim "  foo bar  baz \r\n\t" " " #:repeat? #t)

"foo bar  baz \r\n\t"
> (string-trim "aaaxaayaa" "aa")

"axaay"

procedure

(non-empty-string? x) → boolean?
  x : any/c

x가 문자열이고 비어 있지 않으면 #t를, 그렇지 않으면 #f를 반환합니다.

base 패키지의 6.3 버전에서 추가되었습니다.

procedure

(string-find s contained) → (or/c exact-nonnegative-integer? #f)
  s : string?
  contained : string?

procedure

(string-contains? s contained) → boolean?
  s : string?
  contained : string?

procedure

(string-prefix? s prefix) → boolean?
  s : string?
  prefix : string?

procedure

(string-suffix? s suffix) → boolean?
  s : string?
  suffix : string?

각각 s가 어떤 위치에 두 번째 인자를 포함하는지, 시작하는지, 끝나는지 검사합니다. string-find 함수는 contained가 발견되면 s 안의 첫 위치를 반환하고, string-contains?는 발견되었는지만 보고합니다.

예시:

> (string-prefix? "Racket" "R")

#t
> (string-prefix? "Jacket" "R")

#f
> (string-suffix? "Racket" "et")

#t
> (string-find "Racket" "ack")

1
> (string-contains? "Racket" "ack")

#t

base 패키지의 6.3 버전에서 추가됨. 8.15.0.7 버전에서 변경됨: string-find 추가.

Converting Values to Strings

(require racket/format) ; package: base

이 섹션에 문서화된 바인딩은 racket/formatracket 라이브러리가 제공하지만, racket/base는 제공하지 않습니다.

racket/format 라이브러리는 Racket 값을 문자열로 변환하는 함수들을 제공합니다. 패딩과 숫자 포맷 같은 기능 외에도, 이 함수들은 format(포맷 문자열 사용), number->string, string-append보다 짧다는 장점이 있습니다.

procedure

(~a v
  ...
  [#:separator separator
  #:width width
  #:max-width max-width
  #:min-width min-width
  #:limit-marker limit-marker
  #:limit-prefix? limit-prefix?
  #:align align
  #:pad-string pad-string
  #:left-pad-string left-pad-string
  #:right-pad-string right-pad-string]) → string?

  v : any/c
  separator : string? = ""
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)

  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = ""
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

v를 표시 모드로 문자열로 변환합니다—즉 (format "~a" v)처럼—그런 다음 연속 항목들 사이에 separator를 넣어 결과들을 이어붙이고, 문자열을 최소 min-width 문자, 최대 max-width 문자가 되도록 채우거나 잘라냅니다.

예시:

> (~a "north")

"north"
> (~a 'south)

"south"
> (~a #"east")

"east"
> (~a #\w "e" 'st)

"west"
> (~a (list "red" 'green #"blue"))

"(red green blue)"
> (~a 17)

"17"
> (~a #e1e20)

"100000000000000000000"
> (~a pi)

"3.141592653589793"
> (~a (expt 6.1 87))

"2.1071509386211452e+68"

~a 함수는 주로 문자열, 숫자, 다른 원자 데이터에 유용합니다. ~v~s 함수는 복합 데이터에 더 적합합니다.

sv들의 이어붙여진 문자열 형태와 구분 기호라 하자. smax-width 문자보다 길면 정확히 max-width 문자로 잘립니다. smin-width 문자보다 짧으면 정확히 min-width 문자로 채워집니다. 그렇지 않으면 s가 그대로 반환됩니다. min-widthmax-width보다 크면 예외가 발생합니다.

smax-width 문자보다 길면 잘리고 문자열의 끝이 limit-marker로 대체됩니다. limit-markermax-width보다 길면 예외가 발생합니다. limit-prefix?#t이면, 문자열의 끝 대신 시작이 잘립니다.

예시:

> (~a "abcde" #:max-width 5)

"abcde"
> (~a "abcde" #:max-width 4)

"abcd"
> (~a "abcde" #:max-width 4 #:limit-marker "*")

"abc*"
> (~a "abcde" #:max-width 4 #:limit-marker "...")

"a..."
> (~a "The quick brown fox" #:max-width 15 #:limit-marker "")

"The quick brown"
> (~a "The quick brown fox" #:max-width 15 #:limit-marker "...")

"The quick br..."
> (~a "The quick brown fox" #:max-width 15 #:limit-marker "..." #:limit-prefix? #f)

"The quick br..."

smin-width보다 짧으면 최소 min-width 문자로 채워집니다. align'left이면 오른쪽 패딩만 추가되고, align'right이면 왼쪽 패딩만 추가되며, align'center이면 대략 같은 양의 왼쪽 패딩과 오른쪽 패딩이 추가됩니다.

패딩은 비어 있지 않은 문자열로 지정됩니다. 왼쪽 패딩은 가능한 한 많이 통째로 반복되는 left-pad-string과 그 뒤의, 남은 공간을 채우는 left-pad-string의 접두사로 구성됩니다. 대조적으로 오른쪽 패딩은 right-pad-string의 접미사와 그 뒤의, 통째로 반복되는 right-pad-string의 여러 복사본으로 구성됩니다. 따라서 왼쪽 패딩은 left-pad-string의 시작으로 시작하고 오른쪽 패딩은 right-pad-string의 끝으로 끝납니다.

예시:

> (~a "apple" #:min-width 20 #:align 'left)

"apple               "
> (~a "pear" #:min-width 20 #:align 'left #:right-pad-string " .")

"pear . . . . . . . ."
> (~a "plum" #:min-width 20 #:align 'right #:left-pad-string ". ")

". . . . . . . . plum"
> (~a "orange" #:min-width 20 #:align 'center
                #:left-pad-string "- " #:right-pad-string " -")

"- - - -orange- - - -"

width를 사용해 max-widthmin-width를 동시에 설정해, 결과 문자열이 정확히 width 문자 길이가 되도록 보장합니다:

> (~a "terse" #:width 6)

"terse "
> (~a "loquacious" #:width 6)

"loquac"

procedure

(~v v
  ...
  [#:separator separator
  #:width width
  #:max-width max-width
  #:min-width min-width
  #:limit-marker limit-marker
  #:limit-prefix? limit-prefix?
  #:align align
  #:pad-string pad-string
  #:left-pad-string left-pad-string
  #:right-pad-string right-pad-string]) → string?

  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)

  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

~a와 같지만, 각 값이 (format "~v" v)처럼 변환되고 기본 separator" "이며 기본 limit marker가 "..."입니다.

예시:

> (~v "north")

"\"north\""
> (~v 'south)

"'south"
> (~v #"east")

"#\"east\""
> (~v #\w)

"#\\w"
> (~v (list "red" 'green #"blue"))

"'(\"red\" green #\"blue\")"

Racket 값들에 대해 이야기하는 텍스트를 만들려면 ~v를 사용하세요.

예시:

> (let ([nums (for/list ([i 10]) i)])
    (~a "The even numbers in " (~v nums)
        " are " (~v (filter even? nums)) "."))

"The even numbers in '(0 1 2 3 4 5 6 7 8 9) are '(0 2 4 6 8)."

procedure

(~s v
  ...
  [#:separator separator
  #:width width
  #:max-width max-width
  #:min-width min-width
  #:limit-marker limit-marker
  #:limit-prefix? limit-prefix?
  #:align align
  #:pad-string pad-string
  #:left-pad-string left-pad-string
  #:right-pad-string right-pad-string]) → string?

  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)

  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

~a와 같지만, 각 값이 (format "~s" v)처럼 변환되고 기본 separator" "이며 기본 limit marker가 "..."입니다.

예시:

> (~s "north")

"\"north\""
> (~s 'south)

"south"
> (~s #"east")

"#\"east\""
> (~s #\w)

"#\\w"
> (~s (list "red" 'green #"blue"))

"(\"red\" green #\"blue\")"

procedure

(~e v
  ...
  [#:separator separator
  #:width width
  #:max-width max-width
  #:min-width min-width
  #:limit-marker limit-marker
  #:limit-prefix? limit-prefix?
  #:align align
  #:pad-string pad-string
  #:left-pad-string left-pad-string
  #:right-pad-string right-pad-string]) → string?

  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)

  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

~a와 같지만, 각 값이 (format "~e" v)처럼 변환되고 기본 separator" "이며 기본 limit marker가 "..."입니다.

예시:

> (~e "north")

"\"north\""
> (~e 'south)

"'south"
> (~e #"east")

"#\"east\""
> (~e #\w)

"#\\w"
> (~e (list "red" 'green #"blue"))

"'(\"red\" green #\"blue\")"

procedure

(~r x
  [#:sign sign
  #:base base
  #:precision precision
  #:notation notation
  #:format-exponent format-exponent
  #:min-width min-width
  #:pad-string pad-string
  #:groups groups
  #:group-sep group-sep
  #:decimal-sep decimal-sep]) → string?

  x : rational?
  sign : (or/c #f '+ '++ 'parens
      (let ([ind (or/c string? (list/c string? string?))])
        (list/c ind ind ind)))

   = #f

  base : (or/c (integer-in 2 36) (list/c 'up (integer-in 2 36)))
   = 10

  precision : (or/c exact-nonnegative-integer?
      (list/c '= exact-nonnegative-integer?))
 = 6

  notation : (or/c 'positional 'exponential
      (-> rational? (or/c 'positional 'exponential)))

   = 'positional

  format-exponent : (or/c #f string? (-> exact-integer? string?))
   = #f

  min-width : exact-positive-integer? = 1
  pad-string : non-empty-string? = " "
  groups : (non-empty-listof exact-positive-integer?) = '(3)
  group-sep : string? = ""
  decimal-sep : string? = "."

유리수 xnotation에 따라 positional 또는 exponential 표기법으로 문자열로 변환합니다. x의 정확성(정확/부정확)은 포맷에 영향을 주지 않습니다.

선택적 인자들은 숫자 포맷을 제어합니다:

  • notation — 숫자를 positional 표기법으로 출력할지 exponential 표기법으로 출력할지 결정합니다. notation이 함수이면 x에 적용되어 사용할 표기법을 얻습니다.

예시:

> (~r 12345)

"12345"
> (~r 12345 #:notation 'exponential)

"1.2345e+04"
> (let ([pick-notation
         (lambda (x)
           (if (or (< (abs x) 0.001) (> (abs x) 1000))
               'exponential
               'positional))])
    (for/list ([i (in-range 1 5)])
      (~r (expt 17 i) #:notation pick-notation)))

'("17" "289" "4.913e+03" "8.3521e+04")
  • precision — 소수점(더 정확히는 기수점, radix point) 뒤의 자릿수를 제어합니다. x가 exponential 형태로 포맷될 때 precision은 가수(significand)에 적용됩니다.

precision이 자연수이면 최대 precision 자리가 표시되지만, 끝의 0들은 버려지고, 소수점 뒤의 모든 자리가 버려지면 소수점도 버려집니다. precision(list '= digits)이면 소수점 뒤에 정확히 digits 자리가 사용되고, 소수점은 결코 버려지지 않습니다.

예시:

> (~r pi)

"3.141593"
> (~r pi #:precision 4)

"3.1416"
> (~r pi #:precision 0)

"3"
> (~r 1.5 #:precision 4)

"1.5"
> (~r 1.5 #:precision '(= 4))

"1.5000"
> (~r 50 #:precision 2)

"50"
> (~r 50 #:precision '(= 2))

"50.00"
> (~r 50 #:precision '(= 0))

"50."
  • decimal-sep는 어떤 소수 구분 기호가 출력되는지 지정합니다.

예시:

> (~r 123.456)

"123.456"
> (~r 123.456 #:decimal-sep ",")

"123,456"
  • groups는 숫자의 정수부 자릿수가 어떻게 그룹들로 나뉘는지 제어합니다. 가장 오른쪽 groups 숫자들이 정수부의 가장 오른쪽 자릿수를 그룹화하는 데 사용됩니다. 가장 왼쪽 groups 숫자는 왼쪽 자릿수들을 그룹화하는 데 반복 사용됩니다. group-sep 인자는 자릿수 그룹들 사이에 사용할 구분 기호를 지정합니다.

예시:

> (~r 1234567890 #:groups '(3) #:group-sep ",")

"1,234,567,890"
> (~r 1234567890 #:groups '(3 2) #:group-sep ",")

"12,345,678,90"
> (~r 1234567890 #:groups '(1 3 2) #:group-sep "_")

"1_2_3_4_5_678_90"
  • min-widthx가 보통 min-width보다 적은 자릿수(소수점 포함, 부호 표시는 제외)로 출력된다면, 자릿수들이 pad-string을 사용해 왼쪽 패딩됩니다.

예시:

> (~r 17)

"17"
> (~r 17 #:min-width 4)

"  17"
> (~r -42 #:min-width 4)

"-  42"
> (~r 1.5 #:min-width 4)

" 1.5"
> (~r 1.5 #:precision 4 #:min-width 10)

"      1.5"
> (~r 1.5 #:precision '(= 4) #:min-width 10)

"    1.5000"
> (~r #e1e10 #:min-width 6)

"10000000000"
  • pad-string — 숫자를 최소 min-width 문자(부호 표시 제외)로 채우는 데 사용되는 문자열을 지정합니다. 패딩은 부호와 x의 정상 자릿수 사이에 배치됩니다.

예시:

> (~r 17 #:min-width 4 #:pad-string "0")

"0017"
> (~r -42 #:min-width 4 #:pad-string "0")

"-0042"
  • sign — 숫자의 부호가 어떻게 표시되는지 제어합니다:

    • sign#f(기본)이면, x가 양수이거나 0이면 부호 출력이 생성되지 않고, x가 음수이면 마이너스 부호가 접두됩니다.

    예시:

    > (for/list ([x '(17 0 -42)]) (~r x))
    
    '("17" "0" "-42")
    
    • sign'+이면, x가 0이면 부호 출력이 생성되지 않고, x가 양수이면 플러스 부호가 접두되며, x가 음수이면 마이너스 부호가 접두됩니다.

    예시:

    > (for/list ([x '(17 0 -42)]) (~r x #:sign '+))
    
    '("+17" "0" "-42")
    
    • sign'++이면, x가 0이거나 양수이면 플러스 부호가 접두되고, x가 음수이면 마이너스 부호가 접두됩니다.

    예시:

    > (for/list ([x '(17 0 -42)]) (~r x #:sign '++))
    
    '("+17" "+0" "-42")
    
    • sign'parens이면, x가 0이거나 양수이면 부호 출력이 생성되지 않고, x가 음수이면 숫자가 괄호 안에 둘러싸입니다.

    예시:

    > (for/list ([x '(17 0 -42)]) (~r x #:sign 'parens))
    
    '("17" "0" "(42)")
    
    • sign(list pos-ind zero-ind neg-ind)이면, pos-ind, zero-ind, neg-ind가 각각 양수, 0, 음수를 나타내는 데 사용됩니다. 각 표시자는 접두사로 사용될 문자열이거나 접두사와 접미사를 포함하는 두 문자열 리스트입니다.

    예시:

    > (let ([sign-table '(("" " up") "an even " ("" " down"))])
        (for/list ([x '(17 0 -42)]) (~r x #:sign sign-table)))
    
    '("17 up" "an even 0" "42 down")
    

    기본 동작은 '("" "" "-")와 동등합니다. 'parens 모드는 '("" "" ("(" ")"))와 동등합니다.

  • basex가 포맷되는 진법을 제어합니다. base가 10보다 큰 숫자이면 소문자들이 사용됩니다. base(list 'up base*)이고 base*가 10보다 크면 대문자들이 사용됩니다.

예시:

> (~r 100 #:base 7)

"202"
> (~r 4.5 #:base 2)

"100.1"
> (~r 3735928559 #:base 16)

"deadbeef"
> (~r 3735928559 #:base '(up 16))

"DEADBEEF"
> (~r 3735928559 #:base '(up 16) #:notation 'exponential)

"D.EADBEF*16^+07"
  • format-exponent — 지수가 어떻게 표시되는지 결정합니다.

format-exponent이 문자열이면, 지수는 (부호 '++처럼) 명시적 부호와 최소 두 자리를 갖고, "지수 마커" format-exponent로 가수와 구분되어 표시됩니다:

> (~r 1234 #:notation 'exponential #:format-exponent "E")

"1.234E+03"

format-exponent#f이면, "지수 마커"는 base가 10이면 "e"이고, 그렇지 않으면 base를 포함한 문자열입니다:

> (~r 1234 #:notation 'exponential)

"1.234e+03"
> (~r 1234 #:notation 'exponential #:base 8)

"2.322*8^+03"

format-exponent이 절차이면 지수에 적용되고, 결과 문자열이 가수에 이어붙여집니다:

> (~r 1234 #:notation 'exponential
           #:format-exponent (lambda (e) (format "E~a" e)))

"1.234E3"

base 패키지의 8.5.0.5 버전에서 변경됨: #:groups, #:group-sep, #:decimal-sep 추가.

procedure

(~.a v
  ...
  [#:separator separator
  #:width width
  #:max-width max-width
  #:min-width min-width
  #:limit-marker limit-marker
  #:limit-prefix? limit-prefix?
  #:align align
  #:pad-string pad-string
  #:left-pad-string left-pad-string
  #:right-pad-string right-pad-string]) → string?

  v : any/c
  separator : string? = ""
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)

  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = ""
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

procedure

(~.v v
  ...
  [#:separator separator
  #:width width
  #:max-width max-width
  #:min-width min-width
  #:limit-marker limit-marker
  #:limit-prefix? limit-prefix?
  #:align align
  #:pad-string pad-string
  #:left-pad-string left-pad-string
  #:right-pad-string right-pad-string]) → string?

  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)

  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

procedure

(~.s v
  ...
  [#:separator separator
  #:width width
  #:max-width max-width
  #:min-width min-width
  #:limit-marker limit-marker
  #:limit-prefix? limit-prefix?
  #:align align
  #:pad-string pad-string
  #:left-pad-string left-pad-string
  #:right-pad-string right-pad-string]) → string?

  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)

  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

~a, ~v, ~s와 같지만, 각 v가 각각 (format "~.a" v), (format "~.v" v), (format "~.s" v)처럼 포맷됩니다.

더 알아보기

  • Racket Guide의 문자열(Strings) 문서
  • 문자(Characters)와 바이트 문자열(Byte Strings) 관련 문서
  • 시퀀스(Sequences) 관련 문서