文字列データ型は、文字、数字、および記号の配列です。これは、ほとんどのテキストベースの情報を格納するためのデータ型です。
文字列の宣言
文字列変数を宣言するには、文字の周りに引用符を付けます。通常は二重引用符(")を使用しますが、単一引用符(')も使用できます。文字列に単一引用符または二重引用符を含めたい場合は、文字列を他のタイプの引用符で囲むか、エスケープ引用符を使用してください。
local string1 = "Hello world!"print(string1) --> Hello world!local string2 = 'Hello "world"!'print(string2) --> Hello "world"!
単一引用符と二重引用符の両方を文字列に含めるか、複数行の文字列を作成するには、二重ブラケットを使用して宣言します:
local string1 = [[Helloworld!Hello "world"!Hello 'world'!]]print(string1)--> Hello--> world!--> Hello "world"!--> Hello 'world'!
必要に応じて、同じ数の等号を最初と最後のブラケットに使って、文字列の中に複数のブラケットをネストすることができます:
local string1 = [=[Hello[[world!]]]=]print(string1)--> Hello--> [[world!]]
文字列の結合
文字列を結合するには、連結演算子の二つのドット(..)を使用します。文字列を連結する際には、間にスペースが挿入されないため、前の文字列の終わりまたは次の文字列の始まりにスペースを含めるか、二つの文字列の間にスペースを連結する必要があります。
local hello = "Hello"local helloWithSpace = "Hello "local world = "world!"local string1 = hello .. worldlocal string2 = helloWithSpace .. worldlocal string3 = hello .. " " .. worldprint(string1) --> Helloworld!print(string2) --> Hello world!print(string3) --> Hello world!
print() コマンドは複数の引数を取り、スペースでそれらを結合するため、.. の代わりに , を使用して print() の出力にスペースを挿入することができます。
local hello = "Hello"local world = "world"local exclamationMark = "!"print(hello .. world .. exclamationMark) --> Helloworld!print(hello, world .. exclamationMark) --> Hello world!print(hello, world, exclamationMark) --> Hello world !
文字列の変換
文字列を数値に変換するには、tonumber() 関数を使用します。文字列に数値の表現がない場合、tonumber() は nil を返します。
local numericString = "123"print(tonumber(numericString)) --> 123local alphanumericString = "Hello123"print(tonumber(alphanumericString)) --> nil
文字列のエスケープ
ダブルまたはシングルクォートの文字列宣言をエスケープし、ほぼ任意の文字を埋め込むためには、文字の前にバックスラッシュ(\)を付けます。例えば:
- シングルクォートの文字列にシングルクォートを埋め込むには、\' を使用します。
- ダブルクォートの文字列にダブルクォートを埋め込むには、\" を使用します。
local string1 = 'Hello \'world\'!'print(string1) --> Hello 'world'!local string2 = "Hello \"world\"!"print(string2) --> Hello "world"!
バックスラッシュの後に続く特定の文字は、エスケープされた文字ではなく特別な文字を生成します:
- 新しい行を埋め込むには、\n を使用します。
- 水平タブを埋め込むには、\t を使用します。
local string1 = "Hello\nworld!"print(string1)--> Hello--> world!local string2 = "Hello\tworld!"print(string2) --> Hello world!
文字列補間
Luauは文字列補間をサポートしており、これは文字列の中に式を挿入する機能です。バックティック(`)を使って補間された文字列を宣言し、波カッコの中に式を追加します:
local world = "world"local string1 = `Hello {world}!`print(string1) --> Hello world!
変数が最も一般的な使用法ですが、数学を含む任意の式を使用することができます:
local world = "world"local number = 1local letters = {"w", "o", "r", "l", "d"}local string1 = `Hello {world}, {number} time!`local string2 = `Hello {world}, {number + 1} times!`local string3 = `Hello {table.concat(letters)} a third time!`print(string1) --> Hello world, 1 time!print(string2) --> Hello world, 2 times!print(string3) --> Hello world a third time!
バックティック、波カッコ、およびバックスラッシュには標準的なエスケープルールが適用されます:
local string1 = `Hello \`\{world\}\`!`print(string1) --> Hello `{world}`!
数学変換
文字列に数学演算を行うと、Luauは自動的に文字列を数値に変換します。文字列に数値の表現がない場合、エラーを発生させます。
print("55" + 10) --> 65print("55" - 10) --> 45print("55" * 10) --> 550print("55" / 10) --> 5.5print("55" % 10) --> 5print("Hello" + 10) --> print("Hello" + 10):1: attempt to perform arithmetic (add) on string and number
比較
文字列は <、<=、>、および >= 演算子を使用して比較でき、これは各文字のASCIIコードに基づいて辞書式順序で比較します。 このため、文字列に数字が含まれている場合、正しく比較されないことがあります。例えば、"100" は "20" よりも小さいと見なされます。なぜなら、バイトの "0" と "1" はバイトの "2" よりも小さいASCIIコードを持っているからです。
print("Apple" < "apple") --> trueprint("Banana" < "apple") --> true (BはASCIIでaより前)print("number100" < "number20") --> true
文字列パターンリファレンス
文字列パターンは、string.match()、string.gmatch()、および他の関数で使用できる文字の組み合わせで、長い文字列の部分やサブストリングを見つけるために用いられます。
直接マッチ
Luauの関数 string.match() では、マジックキャラクターを除いて、直接マッチを使用できます。例えば、これらのコマンドは文字列内の Roblox という言葉を探します:
local match1 = string.match("Welcome to Roblox!", "Roblox")local match2 = string.match("Welcome to my awesome game!", "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("What is roblox#com?", "roblox.com")print(match1) --> roblox#com-- ピリオドを % でエスケープして、文字通りのピリオド文字として解釈させますlocal match2 = string.match("I love roblox.com!", "roblox%.com")print(match2) --> roblox.com
アンカー
文字列の先頭または末尾でパターンを検索するには、^ と $ 記号を使用します。
local start1 = string.match("first second third", "^first") -- "first" が先頭にあるのでマッチしますprint(start1) --> firstlocal start2 = string.match("third second first", "^first") -- "first" が先頭にないのでマッチしませんprint(start2) --> nillocal end1 = string.match("first second third", "third$") -- "third" が末尾にあるのでマッチしますprint(end1) --> thirdlocal end2 = string.match("third second first", "third$") -- "third" が末尾にないのでマッチしませんprint(end2) --> nil
^ と $ を一緒に使って、パターンが全体の文字列にのみマッチすることを保証し、部分的にマッチしないようにできます。
-- 完全な文字列にまたがって両方の ^ と $ を使用してマッチしますlocal match1 = string.match("Roblox", "^Roblox$") -- "Roblox" が全体の文字列であるのでマッチします(等価)print(match1) --> Robloxlocal match2 = string.match("I play Roblox", "^Roblox$") -- "Roblox" が先頭と末尾にないのでマッチしませんprint(match2) --> nillocal match3 = string.match("I play Roblox", "Roblox") -- "Roblox" が "I play Roblox" の中に含まれているのでマッチしますprint(match3) --> Roblox
クラス修飾子
キャラクタークラスは、それ自体では文字列内の1つの文字しかマッチしません。たとえば、次のパターン("%d")は文字列を左から右に読み取り、最初の数字(2)を見つけて停止します。
local match = string.match("The Cloud Kingdom has 25 power gems", "%d")print(match) --> 2
修飾子を使って、任意のキャラクタークラスを制御することができます:
| 量指定子 | 意味 |
|---|---|
| + | 前のキャラクタークラスの1回以上のマッチ |
| - | 前のキャラクタークラスの可能な限り少なくマッチ |
| * | 前のキャラクタークラスの0回以上のマッチ |
| ? | 前のキャラクタークラスの1回以下のマッチ |
| %n | n が1と9の間で、キャプチャされた文字列のn番目に等しいサブ文字列をマッチします。 |
| %bxy | x、y、およびそれらの間のすべてをマッチさせるバランスの取れたキャプチャ |
同じパターンに修飾子を追加すると("%d+" を "%d" の代わりに使用することで)、次のように出力されます:
local match1 = string.match("The Cloud Kingdom has 25 power gems", "%d")print(match1) --> 2local match2 = string.match("The Cloud Kingdom has 25 power gems", "%d+")print(match2) --> 25
クラスセット
セットは、単一の文字クラスで全ての仕事をすることができない場合に使用します。たとえば、小文字の文字(%l)と句読点キャラクター(%p)の両方を単一のパターンを使ってマッチさせたい場合です。
セットは角括弧 [] で定義されます。次の例では、セット("[%l%p]+")を使用した場合と使用しない場合("%l%p+")の違いを示しています。
local match1 = string.match("Hello!!! I am another string.", "[%l%p]+") -- セットprint(match1) --> ello!!!local match2 = string.match("Hello!!! I am another string.", "%l%p+") -- 非セットprint(match2) --> o!!!
最初のコマンド(セット)は、Luauに小文字の文字と句読点の両方を見つけるように指示します。セット全体の後に + 量指定子を追加することで、すべてのこれらの文字(ello!!!)を見つけ、スペースに達すると停止します。
二番目のコマンド(非セット)は、+ 量指定子がその前の %p クラスのみに適用されるため、Luau は最初の小文字の文字(o)の前にある句読点(!!!)を取得するだけです。
キャラクタークラスと同様に、セットも自身の「反対」となることができます。これはセットの始まり(開き[のすぐ後)に ^ 文字を追加することで行います。たとえば、"[%p%s]+" は句読点とスペースの両方を表し、"[^%p%s]+" は句読点とスペース以外のすべての文字を表します。
セットでは、特定の文字の範囲を見つけることができる範囲もサポートされています。これは、Lua 5.1マニュアルに詳しく記載されています。
文字列キャプチャ
文字列のキャプチャは、パターン内のサブパターンです。これらは丸括弧 () で囲まれ、マッチしたサブ文字列を取得(キャプチャ)して変数に保存するために使用されます。たとえば、次のパターンには、成功するマッチの際に二つのキャプチャ (%a+) と (%d+) が含まれます。
local pattern = "(%a+)%s?=%s?(%d+)"local key1, val1 = string.match("TwentyOne = 21", pattern)print(key1, val1) --> TwentyOne 21local key2, val2 = string.match("TwoThousand= 2000", pattern)print(key2, val2) --> TwoThousand 2000local key3, val3 = string.match("OneMillion=1000000", pattern)print(key3, val3) --> OneMillion 1000000
? 量指定子は両方の %s クラスの後についており、= 記号の周りのスペースがオプションであることを示すために安全に追加されています。つまり、等号の周りのスペースが1つ(または両方)が欠けていてもマッチが成功します。
string.gsub() 関数では、キャプチャグループを置換文字列の中で %1、%2、%3 などとして使用することができます。Luauは32のキャプチャグループまでサポートしていますが、この構文では最初の9つだけ参照できます。
local str = "love2play Roblox"local pattern = "(%w+)(%d+)(%w+)%s+(%w+)"local replacement = "I %1 %2 %3 %4!"local result = string.gsub(str, pattern, replacement)print(result) --> I love 2 play Roblox!
文字列キャプチャをネストすることもできます。
local places = "The Cloud Kingdom is heavenly, The Forest Kingdom is peaceful"local pattern = "(The%s(%a+%sKingdom)[%w%s]+)"for description, kingdom in string.gmatch(places, pattern) doprint(description)print(kingdom)end--> The Cloud Kingdom is heavenly--> Cloud Kingdom--> The Forest Kingdom is peaceful--> Forest Kingdom
このパターン検索は次のように機能します:
string.gmatch() イテレータは、外側の括弧のペアで定義された全体の「説明」パターンにマッチを探します。これが最初のカンマで停止し、次の内容をキャプチャします:
| # | パターン | キャプチャ |
|---|---|---|
| 1 | (The%s(%a+%sKingdom)[%w%s]+) | The Cloud Kingdom is heavenly |
イテレータは最初のキャプチャを成功させた後、内側のペアの括弧で定義された「王国」パターンにマッチを探します。このネストされたパターンは、単純に次の内容をキャプチャします:
| # | パターン | キャプチャ |
|---|---|---|
| 2 | (%a+%sKingdom) | Cloud Kingdom |
その後、イテレータはバックアウトして全体の文字列の検索を続け、次の内容をキャプチャします:
| # | パターン | キャプチャ |
|---|---|---|
| 3 | (The%s(%a+%sKingdom)[%w%s]+) | The Forest Kingdom is peaceful |
| 4 | (%a+%sKingdom) | Forest Kingdom |
上記のすべてに加えて、空のキャプチャ(())には特別なケースがあります。空のキャプチャがある場合、文字列内の位置がキャプチャされます:
local match1 = "Where does the capture happen? Who knows!"local match2 = "This string is longer than the first one. Where does the capture happen? Who knows?!"local pattern = "()Where does the capture happen%? Who knows!()"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 = "The Cloud Kingdom is heavenly, The Forest Kingdom is peaceful."local pattern = "The (%a+()) Kingdom is %a+"for kingdom, position in string.gmatch(places, pattern) doprint(kingdom, position)end--> Cloud 10--> Forest 42
返された値は、文字列ではなく数値です:
local match = "This is an example"local pattern = "This is an ()example"local position = string.match(match, pattern)print(typeof(position)) --> number