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]]])
문자열 s의 i에서 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에서 아스키 문자(0
127)는 1바이트, 그 외 문자는 24바이트로 인코딩돼요. #s는 바이트 수를 세므로, UTF-8 문자열의 "길이"(문자 수)를 구하려면utf8.len을 써야 해요.string.sub,string.len등string라이브러리는 바이트 단위로 동작해요. 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 문자열에서 개별 "문자"는 1~4바이트로 표현되며, utf8.codepoint·utf8.len·utf8.offset은 이를 코드 포인트 단위로 다뤄요. 문자열의 물리적 크기가 필요하면 바이트 길이(#)를 쓰는 게 정확해요.
반복자
utf8.codes는 문자의 위치와 값을 순회하는 유일한 반복자 함수예요. 패턴 매칭에서 utf8.charpattern을 사용하면 각 코드 포인트 경계에 맞춰 문자를 매칭할 수 있어요.