문자열 데이터 유형은 문자, 숫자 및 기호와 같은 문자 시퀀스입니다. 대부분의 텍스트 기반 정보를 저장하는 데이터 유형입니다.
문자열 선언
문자열 변수를 선언하려면 문자 주위에 따옴표를 추가합니다. 일반적으로 이중 따옴표(")를 사용하는 것이 일반적이지만, 단일 따옴표(')도 작동합니다. 문자열에 단일 따옴표 또는 이중 따옴표를 포함하고 싶다면, 문자열을 다른 유형의 따옴표로 감싸거나 이스케이프된 따옴표를 사용하세요.
local string1 = "안녕하세요, 세계!"print(string1) --> 안녕하세요, 세계!local string2 = '안녕하세요, "세계"!'print(string2) --> 안녕하세요, "세계"!
단일 따옴표와 이중 따옴표를 모두 포함하거나 멀티라인 문자열을 생성하려면, 이중 대괄호를 사용하여 선언합니다:
local string1 = [[안녕하세요세계!안녕하세요 "세계"!안녕하세요 '세계'!]]print(string1)--> 안녕하세요--> 세계!--> 안녕하세요 "세계"!--> 안녕하세요 '세계'!
필요한 경우, 같은 수의 등호로 시작하는 대괄호를 문자열 내부에 중첩할 수 있습니다:
local string1 = [=[안녕하세요[[세계!]]]=]print(string1)--> 안녕하세요--> [[세계!]]
문자열 결합
문자열을 결합하려면 두 개의 점(..)으로 연결합니다. 문자열을 연결하면 사이에 공백이 삽입되지 않으므로, 이전 또는 다음 문자열의 끝/시작에 공백을 포함하거나 두 문자열 사이에 공백을 연결해야 합니다.
local hello = "안녕하세요"local helloWithSpace = "안녕하세요 "local world = "세계!"local string1 = hello .. worldlocal string2 = helloWithSpace .. worldlocal string3 = hello .. " " .. worldprint(string1) --> 안녕하세요세계!print(string2) --> 안녕하세요 세계!print(string3) --> 안녕하세요 세계!
print() 명령은 여러 인수를 받아 공백으로 결합하므로, .. 대신 ,를 사용하여 print() 출력에 공백을 생성할 수 있습니다.
local hello = "안녕하세요"local world = "세계"local exclamationMark = "!"print(hello .. world .. exclamationMark) --> 안녕하세요세계!print(hello, world .. exclamationMark) --> 안녕하세요 세계!print(hello, world, exclamationMark) --> 안녕하세요 세계 !
문자열 변환
문자열을 숫자로 변환하려면 tonumber() 함수를 사용합니다. 문자열에 숫자 표현이 없으면, tonumber()는 nil을 반환합니다.
local numericString = "123"print(tonumber(numericString)) --> 123local alphanumericString = "안녕하세요123"print(tonumber(alphanumericString)) --> nil
문자열 이스케이프
이중 따옴표 또는 단일 따옴표 문자열 선언을 이스케이프하고 거의 모든 문자를 삽입하려면, 문자 앞에 백슬래시(\)를 추가하세요. 예:
- 단일 따옴표 문자열에 단일 따옴표를 삽입하려면 \'를 사용합니다.
- 이중 따옴표 문자열에 이중 따옴표를 삽입하려면 \"를 사용합니다.
local string1 = '안녕하세요 \'세계\'!'print(string1) --> 안녕하세요 '세계'!local string2 = "안녕하세요 \"세계\"!"print(string2) --> 안녕하세요 "세계"!
백슬래시 다음에 특정 문자가 올 경우, 이스케이프 문자가 생성되는 대신 특별한 문자가 만들어집니다:
- 새 줄을 삽입하려면 \n을 사용합니다.
- 수평 탭을 삽입하려면 \t를 사용합니다.
local string1 = "안녕하세요\n세계!"print(string1)--> 안녕하세요--> 세계!local string2 = "안녕하세요\t세계!"print(string2) --> 안녕하세요 세계!
문자열 보간
Luau는 문자열 보간을 지원하는데, 이는 문자열에 표현식을 삽입할 수 있는 기능입니다. 백틱(`)을 사용하여 보간된 문자열을 선언한 후, 중괄호 안에 표현식을 추가합니다:
local world = "세계"local string1 = `안녕하세요 {world}!`print(string1) --> 안녕하세요 세계!
변수가 가장 일반적인 사용이지만, 수학을 포함한 모든 표현식을 사용할 수 있습니다:
local world = "세계"local number = 1local letters = {"w", "o", "r", "l", "d"}local string1 = `안녕하세요 {world}, {number} 시간!`local string2 = `안녕하세요 {world}, {number + 1} 번!`local string3 = `안녕하세요 {table.concat(letters)} 세 번째 시간!`print(string1) --> 안녕하세요 세계, 1 시간!print(string2) --> 안녕하세요 세계, 2 번!print(string3) --> 안녕하세요 세 번째 시간!
백틱, 중괄호 및 백슬래시에 대한 표준 이스케이프 규칙이 적용됩니다:
local string1 = `안녕하세요 \`\{world\}\`!`print(string1) --> 안녕하세요 `{world}`!
수학 변환
문자열에 대해 수학 작업을 수행하면, Luau는 자동으로 문자열을 숫자로 변환합니다. 문자열에 숫자 표현이 없으면 오류를 발생시킵니다.
print("55" + 10) --> 65print("55" - 10) --> 45print("55" * 10) --> 550print("55" / 10) --> 5.5print("55" % 10) --> 5print("안녕하세요" + 10) --> print("안녕하세요" + 10):1: 문자열과 숫자에 대해 산술(더하기) 연산을 시도합니다.
비교
문자열은 <, <=, > 및 >= 연산자를 사용하여 비교할 수 있으며, 이는 문자열의 각 문자에 대한 ASCII 코드에 기반하여 사전식 순서를 사용하여 비교합니다. 이로 인해 문자열의 숫자가 올바르게 비교되지 않아, 예를 들어 "100"이 "20"보다 작아질 수 있습니다. 이는 바이트 "0"과 "1"의 ASCII 코드가 바이트 "2"보다 낮기 때문입니다.
print("사과" < "사과") --> falseprint("바나나" < "사과") --> true (B가 ASCII에서 a보다 먼저 있음)print("숫자100" < "숫자20") --> true
문자열 패턴 참조
문자열 패턴은 string.match(), string.gmatch(), 및 다른 함수와 함께 사용할 수 있는 문자 조합으로, 더 긴 문자열의 일부 또는 부분 문자열을 찾는 데 사용됩니다.
직접 일치
Luau 함수인 string.match()에서 직접 일치를 사용할 수 있으며, 마법 문자를 제외하고 사용합니다. 예를 들어, 이 명령은 문자열 내에서 Roblox 단어를 찾습니다:
local match1 = string.match("환영합니다 Roblox!", "Roblox")local match2 = string.match("내 멋진 게임에 오신 것을 환영합니다!", "Roblox")print(match1) --> Robloxprint(match2) --> nil
문자 클래스
문자 클래스는 더 고급 문자열 검색에 필수적입니다. 문자에 특화되어 있지 않고, 특정 범주(클래스) 내에 맞는 것을 검색하는 데 사용할 수 있습니다. 이러한 범주에는 문자, 숫자, 공백, 구두점 등이 포함됩니다.
다음 표는 Luau 문자열 패턴의 공식 문자 클래스를 보여줍니다:
| 클래스 | 대표하는 것 | 예제 일치 |
|---|---|---|
| . | 모든 문자 | 32kasGJ1%fTlk?@94 |
| %a | 대문자 또는 소문자 | aBcDeFgHiJkLmNoPqRsTuVwXyZ |
| %l | 소문자 | abcdefghijklmnopqrstuvwxyz |
| %u | 대문자 | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
| %d | 모든 숫자(숫자) | 0123456789 |
| %p | 모든 구두점 문자 | !@#;,. |
| %w | 알파벳 문자(문자 또는 숫자) | aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789 |
| %s | 공백 또는 공백 문자 | , \n, 및 \r |
| %c | 특별 제어 문자 | |
| %x | 16진수 문자 | 0123456789ABCDEF |
| %z | NULL 문자(\0) |
한 글자의 문자 클래스인 %a 및 %s의 경우, 대응하는 대문자 문자는 클래스의 "반대"를 나타냅니다. 예를 들어, %p는 구두점 문자를 나타내고, %P는 모든 문자를 나타냅니다(구두점 제외).
마법 문자
특정 용도로 예약된 12개의 "마법 문자"가 있습니다:
| $ | % | ^ | * | ( | ) |
| . | [ | ] | + | - | ? |
마법 문자를 이스케이프하고 검색하려면 % 기호를 사용하세요. 예를 들어, roblox.com을 검색하려면, . (마침표) 기호를 %로 앞서서 이스케이프하면 됩니다 (예: %.).
-- "roblox.com"은 "roblox#com"과 일치합니다. 마침표는 "모든 문자"로 해석되기 때문입니다.local match1 = string.match("roblox#com이 무엇인가요?", "roblox.com")print(match1) --> roblox#com-- 마침표를 %로 이스케이프하여 문자 그대로 마침표로 해석되도록 합니다.local match2 = string.match("나는 roblox.com을 좋아합니다!", "roblox%.com")print(match2) --> roblox.com
앵커
패턴의 시작 또는 끝에서 문자열을 검색하려면 ^ 및 $ 기호를 사용하세요.
local start1 = string.match("첫 번째 두 번째 세 번째", "^첫 번째") -- 시작 부분에서 "첫 번째"와 일치합니다.print(start1) --> 첫 번째local start2 = string.match("세 번째 두 번째 첫 번째", "^첫 번째") -- 시작에 "첫 번째"가 없으므로 일치하지 않음.print(start2) --> nillocal end1 = string.match("첫 번째 두 번째 세 번째", "세 번째$") -- 끝 부분에서 "세 번째"와 일치합니다.print(end1) --> 세 번째local end2 = string.match("세 번째 두 번째 첫 번째", "세 번째$") -- 끝에 "세 번째"가 없으므로 일치하지 않음.print(end2) --> nil
^와 $를 함께 사용하여 패턴이 전체 문자열과 일치하도록 보장할 수 있습니다.
-- ^와 $를 사용하여 전체 문자열과 일치local match1 = string.match("Roblox", "^Roblox$") -- "Roblox"가 전체 문자열과 일치하므로 일치합니다.print(match1) --> Robloxlocal match2 = string.match("나는 Roblox를 합니다", "^Roblox$") -- "Roblox"가 처음과 끝 모두와 일치하지 않으므로 일치하지 않음.print(match2) --> nillocal match3 = string.match("나는 Roblox를 합니다", "Roblox") -- "Roblox"가 "나는 Roblox를 합니다"에 포함되어 있으므로 일치합니다.print(match3) --> Roblox
클래스 수정자
독립적으로 문자 클래스는 문자열 내에서 하나의 문자만 일치합니다. 예를 들어, 다음 패턴("%d")은 문자열을 왼쪽에서 오른쪽으로 읽으며, 첫 번째 숫자(2)를 찾아 멈춥니다.
local match = string.match("클라우드 왕국에 25개의 힘의 보석이 있습니다", "%d")print(match) --> 2
모든 문자 클래스에서 수정자를 사용하여 결과를 제어할 수 있습니다:
| 수량사 | 의미 |
|---|---|
| + | 선행 문자 클래스의 1개 이상의 문자와 일치 |
| - | 선행 문자 클래스의 가능한 가장 적은 개수와 일치 |
| * | 선행 문자 클래스의 0개 이상의 문자와 일치 |
| ? | 선행 문자 클래스의 1개 이하와 일치 |
| %n | 1에서 9 사이의 n에 대해, n번째 캡처된 문자열과 일치합니다. |
| %bxy | 균형을 맞춘 캡처로 x와 y 및 그 사이의 모든 것과 일치합니다 (예: %b()는 괄호 쌍과 그 사이의 모든 것과 일치합니다) |
수정자를 동일한 패턴("%d+" 대신 "%d")에 추가하면, 2 대신 25가 출력됩니다:
local match1 = string.match("클라우드 왕국에 25개의 힘의 보석이 있습니다", "%d")print(match1) --> 2local match2 = string.match("클라우드 왕국에 25개의 힘의 보석이 있습니다", "%d+")print(match2) --> 25
클래스 집합
집합은 단일 문자 클래스가 전체 작업을 수행할 수 없을 때 사용해야 합니다. 예를 들어, 소문자(%l)와 구두점 문자(%p)를 단일 패턴으로 일치시키려면 집합을 사용합니다.
집합은 대괄호 []로 정의됩니다. 다음 예에서는 집합("[%l%p]+")과 집합을 사용하지 않는 경우("%l%p+") 간의 차이를 주목하세요.
local match1 = string.match("안녕하세요!!! 저는 다른 문자열입니다.", "[%l%p]+") -- 집합print(match1) --> 안녕하세요!!!local match2 = string.match("안녕하세요!!! 저는 다른 문자열입니다.", "%l%p+") -- 비집합print(match2) --> 안녕하세요!!!
첫 번째 명령(집합)은 Luau에게 소문자 문자와 구두점을 모두 찾도록 지시합니다. 집합 전체에 + 수량사가 추가되면 모든 해당 문자(안녕하세요!!!)를 찾아 공백에 도달할 때까지 멈춥니다.
두 번째 명령(비집합)에서는 수량사 +가 앞의 %p 클래스에만 적용되므로, Luau는 소문자 문자(안녕하세요)의 첫 번째 문자(ㅇ)만 가져오고 이후에 오는 구두점을 모두 가져옵니다(!!!).
문자 클래스처럼, 집합은 스스로의 "반대"가 될 수 있습니다. 이는 집합의 시작 부에 ^ 문자를 추가하여 지정합니다. 예를 들어, "[%p%s]+"는 구두점 및 공백을 나타내고, "[^%p%s]+"는 구두점 및 공백을 제외한 모든 문자를 나타냅니다.
집합은 또한 범위를 지원하여 시작 문자와 종료 문자 사이의 모든 일치를 찾을 수 있습니다. 이는 Lua 5.1 매뉴얼에서 더 자세히 설명된 고급 기능입니다.
문자열 캡처
문자열 캡처는 패턴 내의 하위 패턴입니다. 이는 괄호 ()로 둘러싸여 있으며, 일치하는 부분 문자열을 가져와서 변수에 저장하는 데 사용됩니다. 예를 들어, 다음 패턴은 두 개의 캡처 (%a+) 및 (%d+)를 포함하며, 성공적인 일치 시 두 개의 하위 문자열을 반환합니다.
local pattern = "(%a+)%s?=%s?(%d+)"local key1, val1 = string.match("이십일 = 21", pattern)print(key1, val1) --> 이십일 21local key2, val2 = string.match("이천 = 2000", pattern)print(key2, val2) --> 이천 2000local key3, val3 = string.match("백만 = 1000000", pattern)print(key3, val3) --> 백만 1000000
? 수량사가 두 개의 %s 클래스 뒤에 붙은 것은 안전한 추가 사항으로, = 기호 양쪽의 공백을 선택적으로 할 수 있게 합니다. 이는 = 기호 주변의 한쪽(또는 두쪽) 공백이 없더라도 일치가 성공한다는 것을 의미합니다.
string.gsub() 함수에서는 대체 문자열에서 캡처 그룹을 %1, %2, %3 등의 형태로 포함할 수 있습니다. Luau는 32개의 캡처 그룹까지 지원하지만, 이 구문으로는 첫 번째 아홉 개만 참조할 수 있습니다:
local str = "사랑2게임 Roblox"local pattern = "(%w+)(%d+)(%w+)%s+(%w+)"local replacement = "나는 %1 %2 %3 %4!"local result = string.gsub(str, pattern, replacement)print(result) --> 나는 사랑 2 게임 Roblox!
문자열 캡처를 중첩할 수도 있습니다:
local places = "클라우드 왕국은 천국처럼, 숲 왕국은 평화롭습니다"local pattern = "(클라우드%s(%a+%s왕국)[%w%s]+)"for description, kingdom in string.gmatch(places, pattern) doprint(description)print(kingdom)end--> 클라우드 왕국은 천국처럼--> 클라우드 왕국--> 숲 왕국은 평화롭습니다--> 숲 왕국
이 패턴 검색은 다음과 같이 작동합니다:
string.gmatch() 반복자는 외부 괄호 쌍으로 정의된 전체 "설명" 패턴에서 일치를 찾습니다. 여기에서 첫 번째 쉼표까지 읽고 다음을 캡처합니다:
| # | 패턴 | 캡처 |
|---|---|---|
| 1 | (클라우드%s(%a+%s왕국)[%w%s]+) | 클라우드 왕국은 천국처럼 |
그런 다음 반복자는 처음 캡처가 성공하면 내부 괄호 쌍으로 정의된 "왕국" 패턴에서 일치를 찾습니다. 이 중첩 패턴은 다음과 같이 캡처합니다:
| # | 패턴 | 캡처 |
|---|---|---|
| 2 | (%a+%s왕국) | 클라우드 왕국 |
그 다음 반복자는 물러나서 전체 문자열을 계속 검색하여 다음을 캡처합니다:
| # | 패턴 | 캡처 |
|---|---|---|
| 3 | (클라우드%s(%a+%s왕국)[%w%s]+) | 숲 왕국은 평화롭습니다 |
| 4 | (%a+%s왕국) | 숲 왕국 |
위의 모든 것 외에도, 빈 캡처(())의 특별한 경우가 있습니다. 캡처가 비어 있는 경우, 문자열 내의 위치가 캡처됩니다:
local match1 = "캡처가 어디서 발생하나요? 누가 아나요!"local match2 = "이 문자열은 첫 번째 것보다 깁니다. 캡처가 어디서 발생하나요? 누가 아나요?!"local pattern = "()캡처가 어디서 발생하나요%? 누가 아나요!()"local start1, finish1 = string.match(match1, pattern)print(start1, finish1) --> 1 42local start2, finish2 = string.match(match2, pattern)print(start2, finish2) --> 43 84
이러한 특별 캡처도 일반 캡처처럼 중첩될 수 있습니다:
local places = "클라우드 왕국은 천국처럼, 숲 왕국은 평화롭습니다."local pattern = "클라우드 (%a+()) 왕국은 %a+"for kingdom, position in string.gmatch(places, pattern) doprint(kingdom, position)end--> 클라우드 10--> 숲 42
반환된 값은 문자열이 아니라 숫자입니다:
local match = "이 예시는 예입니다"local pattern = "이 예시는 ()예시입니다"local position = string.match(match, pattern)print(typeof(position)) --> number