UTF-8 지원

UTF-8 지원 (UTF-8 Support)

utf8 라이브러리는 UTF-8 인코딩 문자열을 다루는 기본 함수들을 제공해요. 루아는 문자열을 바이트 시퀀스로 취급하므로, UTF-8 텍스트에서 "문자"(코드 포인트) 단위로 다루기 위해 이 라이브러리가 필요해요. 모든 함수는 문자열 인자가 유효한 UTF-8이 아닐 때 (매개변수에 따라) 예외를 발생시킬 수 있어요.

utf8.char

utf8.char (...)

각 인자를 UTF-8 문자(코드 포인트)로 해석해, 그것을 UTF-8로 인코딩한 문자열을 만들어 반환해요. 0에서 0x7FFFFFFF 범위의 코드 포인트만 유효해요.

print(utf8.char(65))            --> A
print(utf8.char(0xAC00))        --> 가

utf8.charpattern

utf8.charpattern

루아 패턴에서 UTF-8 문자 하나를 매칭할 수 있는 패턴 문자열을 나타내는 상수예요. string.match 등과 함께 쓸 때 유용해요.

utf8.codes

utf8.codes (s [, lax])

문자열 s를 순회해 각 코드 포인트를 (인덱스, 코드 포인트) 순으로 반환하는 반복자 함수를 반환해요. 일반 for(for p, c in utf8.codes(s))로 사용해요. p는 코드 포인트의 시작 위치(바이트 인덱스), c는 그 코드 포인트 값이에요.

for p, c in utf8.codes("가나다") do
  print(p, c)   -- 위치와 코드포인트 출력
end

lax가 참이면 잘못된 바이트를 무시하고 다음 유효 문자를 찾아 계속해요.

utf8.codepoint

utf8.codepoint (s [, i [, j [, lax]]])

문자열 si에서 j까지(기본 1), 각 문자(코드 포인트)의 정수 값을 반환해요. 여러 문자를 지정하면 여러 값을 반환해요. i, j는 바이트 위치예요. 범위 밖이면 nil을 반환해요.

print(utf8.codepoint("ABC"))          --> 65
print(utf8.codepoint("가나", 1, -1))   --> 44032 45208

utf8.len

utf8.len (s [, i [, j [, lax]]])

문자열 s의 "문자 수"(코드 포인트 개수)를 반환해요. i부터 j까지의 범위(바이트 위치)를 지정할 수 있어요. 문자열이 "표준 UTF-8"이 아니거나 잘못된 바이트 시퀀스를 만나면 nil과 (오류 아니면) 위치를 반환할 수 있어요. lax가 참이면 잘못된 시퀀스를 개별 문자로 세어 반환해요.

print(utf8.len("가나다"))    --> 3

utf8.offset

utf8.offset (s, n [, i])

문자열 s에서 n번째 문자(코드 포인트)의 시작 바이트 위치를 반환해요.

  • n > 0이면 i(기본 1)부터 앞으로 n번째 문자의 위치.
  • n < 0이면 i에서 뒤로 -n번째 문자의 위치.
  • n == 0이면 i가 속한 문자의 시작 위치.
  • 범위를 벗어나면 nil을 반환해요.
print(utf8.offset("가나다", 2))   --> 4

UTF-8 인코딩 참고

  • UTF-8에서 아스키 문자(0127)는 1바이트, 그 외 문자는 24바이트로 인코딩돼요.
  • #s는 바이트 수를 세므로, UTF-8 문자열의 "길이"(문자 수)를 구하려면 utf8.len을 써야 해요.
  • string.sub, string.lenstring 라이브러리는 바이트 단위로 동작해요. UTF-8 문자 단위로 자르려면 utf8.offset이나 utf8.codepoint를 활용하거나, 문자 경계를 계산해야 해요.
-- UTF-8 문자열에서 처음 3문자 잘라내기
local b = utf8.offset(s, 4)   -- 4번째 문자 시작
local head = b and string.sub(s, 1, b - 1) or s

확장성과 한계

utf8 라이브러리는 기본적인 UTF-8 처리만 제공해요. 정규화(normalization), 대소문자 변환, 합성 문자 분해 등의 고급 기능은 포함하지 않아요. 더 풍부한 처리가 필요하면 순수 루아 또는 C로 작성된 별도 라이브러리를 사용해요.

출처: UTF-8 지원 (UTF-8 Support)

본문

바이트와 문자

루아 문자열은 바이트 배열이에요. UTF-8 문자열에서 개별 "문자"는 1~4바이트로 표현되며, utf8.codepoint·utf8.len·utf8.offset은 이를 코드 포인트 단위로 다뤄요. 문자열의 물리적 크기가 필요하면 바이트 길이(#)를 쓰는 게 정확해요.

반복자

utf8.codes는 문자의 위치와 값을 순회하는 유일한 반복자 함수예요. 패턴 매칭에서 utf8.charpattern을 사용하면 각 코드 포인트 경계에 맞춰 문자를 매칭할 수 있어요.

더 알아보기