Lua 文字列
文字列(String)は、数字・英字・アンダースコアから構成される一連の文字です。
Lua において、文字列はテキストデータを格納するための基本的なデータ型です。
Lua の文字列には、英字、数字、記号、スペース、その他の特殊文字を含む任意の文字を含めることができます。
Lua 言語では文字列は以下の3つの方法で表すことができます:
単一引用符(シングルクォート)で囲まれた一連の文字。
local str1 = 'This is a string.' local str2 = "This is also a string."
二重引用符(ダブルクォート)で囲まれた一連の文字。
local str = "Hello, " str = str .. "World!" -- 创建一个新的字符串并将其赋值给str print(str) -- 输出 "Hello, World!"
[[と]][[]] で囲まれた一連の文字。
local multilineString = [[ This is a multiline string. It can contain multiple lines of text. No need for escape characters. ]] print(multilineString)
上記3つの方法の文字列の例は次のとおりです:
例
print("\"文字列 1 は\"",string1)
string2 = 'example.com'
print("文字列 2 は",string2)
string3 = [["Lua チュートリアル"]]
print("文字列 3 は",string3)
上記コードの実行結果は次のとおりです:
"字符串 1 是" Lua 字符串 2 是 example.com 字符串 3 是 "Lua 教程"
文字列の長さの計算
Lua では、文字列の長さ(つまり文字列内の文字数)を計算するには、次を使用できます。string.len関数またはutf8.len関数。中国語を含む場合は通常utf8.len,string.len関数は ASCII 文字のみを含む文字列の長さを計算するために使われます。
例
-- 文字列の長さ(文字数)を計算する
local length = string.len(myString)
print(length) -- 14 を出力
上記の例の myString 文字列は ASCII 文字のみを含むため、string.len関数は文字列の長さを正確に返すことができます。
中国語を含む文字列には次を使います:utf8.len関数:
例
-- 文字列の長さ(文字数)を計算する
local length1 = utf8.len(myString)
print(length1) -- 10 を出力
-- string.len 関数は結果が不正確になります
local length2 = string.len(myString)
print(length2) -- 14 を出力
出力結果は次のとおりです:
10 14
エスケープ文字は、バックスペースキーやキャリッジリターンキーなど、直接表示できない文字を表すために使用されます。例えば、文字列内で二重引用符を表すには \" を使用できます。\。
すべてのエスケープ文字とその意味は次のとおりです:
エスケープ文字
| 意味
| ASCII コード値(10進数)
|
\a
| ベル(BEL)
| 007
|
\b
| バックスペース(BS)。現在位置を前の列に移動します。
| 008
|
\f
| フォームフィード(FF)。現在位置を次のページの先頭に移動します。
| 012
|
\n
| ラインフィード(LF)。現在位置を次の行の先頭に移動します。
| 010
|
\r
| キャリッジリターン(CR)。現在位置を行の先頭に移動します。
| 013
|
\t
| 水平タブ(HT)(次のタブ位置にジャンプ)
| 009
|
\v
| 垂直タブ(VT)
| 011
|
\\
| 1つのバックスラッシュ文字 ''\' を表します。
| 092
|
\'
| 単一引用符(アポストロフィ)文字を表します。
| 039
|
\"
| 二重引用符文字を表します。
| 034
|
\0
| ヌル文字(NULL)
| 000
|
\ddd
| 1〜3桁の8進数で表される任意の文字
| 3桁の8進数
|
\xhh
| 1〜2桁の16進数で表される任意の文字
| 2桁の16進数
|
文字列操作
Lua は文字列操作をサポートするための多くのメソッドを提供します:
| 番号 | メソッド & 用途 |
|---|---|
| 1 | string.upper(argument): 文字列全体を大文字に変換します。 |
| 2 | string.lower(argument): 文字列全体を小文字に変換します。 |
| 3 | string.gsub(mainString,findString,replaceString,num) 文字列内の置換を行います。 mainString は操作対象の文字列、findString は置換される文字、replaceString は置換する文字、num は置換回数(省略可能。省略するとすべて置換)です。例:
> string.gsub("aaaa","a","z",3);
zzza 3
|
| 4 | string.find (str, substr, [init, [plain]]) 指定された対象文字列 str 内で指定された内容 substr を検索し、一致する部分文字列が見つかった場合はその部分文字列の開始インデックスと終了インデックスを返し、存在しない場合は nil を返します。 init検索の開始位置を指定します。デフォルトは 1 で、負数を指定できます。負数は後ろから数えた文字数を表します。 plain簡易モードを使用するかどうかを指定します。デフォルトは false で、true は単純な部分文字列検索のみを行い、false は正規表現パターンマッチングを使用します。 次の例は、文字列 "Lua" の開始インデックスと終了インデックスを検索します:
> string.find("Hello Lua user", "Lua", 1)
7 9
|
| 5 | string.reverse(arg) 文字列の反転
> string.reverse("Lua")
auL |
| 6 | string.format(...) printf に似たフォーマット文字列を返します。
> string.format("the value is:%d",4)
the value is:4
|
| 7 | string.char(arg) と string.byte(arg[,int]) char は整数を文字に変換して連結し、byte は文字を整数値に変換します(任意の文字を指定できます。デフォルトは最初の文字)。
> string.char(97,98,99,100)
abcd
> string.byte("ABCD",4)
68
> string.byte("ABCD")
65
>
|
| 8 | string.len(arg) 文字列の長さを計算します。
string.len("abc")
3
|
| 9 | string.rep(string, n) 文字列 string の n 個のコピーを返します。
> string.rep("abcd",2)
abcdabcd
|
| 10 | .. 2つの文字列を連結します。
> print("www.サンプル.".."com")
www.example.com
|
| 11 | string.gmatch(str, pattern) イテレータ関数を返します。この関数を呼び出すたびに、文字列 str 内で pattern が記述するパターンに一致する次の部分文字列を返します。pattern で記述された文字列が見つからない場合は、イテレータ関数は nil を返します。
> for word in string.gmatch("Hello Lua user", "%a+") do print(word) end
Hello
Lua
user
|
| 12 | string.match(str, pattern, init) string.match() はソース文字列 str 内の最初の一致のみを探します。引数 init は省略可能で、検索の開始位置を指定します。デフォルトは 1 です。 マッチに成功すると、関数はマッチ式内のすべてのキャプチャ結果を返します。キャプチャマークが設定されていない場合は、マッチした文字列全体を返します。マッチに失敗した場合は nil を返します。
> = string.match("I have 2 questions for you.", "%d+ %a+")
2 questions
> = string.format("%d, %q", string.match("I have 2 questions for you.", "(%d+) (%a+)"))
2, "questions"
|
文字列の切り出し
文字列の切り出しには sub() メソッドを使用します。
string.sub() は文字列を切り出すために使われ、プロトタイプは次のとおりです:
string.sub(s, i [, j])
引数の説明:
- s:切り出す対象の文字列。
- i:切り出しの開始位置。
- j:切り出しの終了位置。デフォルトは -1 で、最後の文字を表します。
例
-- 文字列
local sourcestr = "prefix--サンプルgoogletaobao--suffix"
print("\n元の文字列", string.format("%q", sourcestr))
-- 一部を切り出し、4番目から15番目まで
local first_sub = string.sub(sourcestr, 4, 15)
print("\n1回目の切り出し", string.format("%q", first_sub))
-- 文字列の先頭部分を取得、1番目から8番目まで
local second_sub = string.sub(sourcestr, 1, 8)
print("\n2回目の切り出し", string.format("%q", second_sub))
-- 最後の10文字を切り出し
local third_sub = string.sub(sourcestr, -10)
print("\n3回目の切り出し", string.format("%q", third_sub))
-- インデックスが範囲外なので、元の文字列を出力
local fourth_sub = string.sub(sourcestr, -100)
print("\n4回目の切り出し", string.format("%q", fourth_sub))
上記コードの実行結果は次のとおりです:
原始字符串 "prefix--サンプルgoogletaobao--suffix" 第一次截取 "fix--サンプルg" 第二次截取 "prefix--" 第三次截取 "ao--suffix" 第四次截取 "prefix--サンプルgoogletaobao--suffix"
文字列の大文字・小文字変換
次の例は、文字列の大文字・小文字変換方法を示しています:
例
print(string.upper(string1))
print(string.lower(string1))
上記コードの実行結果は次のとおりです:
LUA lua
文字列の検索と反転
次の例は、文字列の検索と反転操作を示しています:
例
-- 文字列を検索
print(string.find(string,"Tutorial"))
reversedString = string.reverse(string)
print("新しい文字列は",reversedString)
上記コードの実行結果は次のとおりです:
5 12 新字符串为 lairotuT auL
文字列のフォーマット
Lua は提供しますstring.format()関数は特定の形式を持つ文字列を生成するために使われます。関数の最初の引数はフォーマットで、その後にフォーマット内の各プレースホルダーに対応するさまざまなデータを指定します。
フォーマット文字列があるおかげで、生成される長い文字列の可読性が大幅に向上します。この関数の形式は C 言語の printf() によく似ています。
次の例は、文字列のフォーマット操作を示しています:
フォーマット文字列には以下のエスケープコードを含めることができます:
- %c - 数字を受け取り、ASCIIコード表の対応する文字に変換します。
- %d, %i - 数字を受け取り、符号付き整数形式に変換します。
- %o - 数字を受け取り、8進数形式に変換します。
- %u - 数字を受け取り、符号なし整数形式に変換します。
- %x - 数字を受け取り、16進数形式に変換します。小文字を使用します。
- %X - 数字を受け取り、16進数形式に変換します。大文字を使用します。
- %e - 数字を受け取り、科学的記数法形式に変換します。小文字の e を使用します。
- %E - 数字を受け取り、科学的記数法形式に変換します。大文字の E を使用します。
- %f - 数字を受け取り、浮動小数点数形式に変換します。
- %g(%G) - 数字を受け取り、%e(%G の場合は %E)と %f のうち短い方の形式に変換します。
- %q - 文字列を受け取り、Lua コンパイラが安全に読み込める形式に変換します。
- %s - 文字列を受け取り、指定されたパラメータに従ってその文字列をフォーマットします。
フォーマットをさらに細かく指定するには、% の後にパラメータを追加できます。パラメータは次の順序で読み込まれます:
- (1) 符号: + 記号は、その後の数値変換指定子で正数に正符号を表示させます。デフォルトでは負数にのみ符号が表示されます。
- (2) プレースホルダー: 0 は、文字列幅が指定された場合の埋め文字です。未指定の場合のデフォルトのプレースホルダーはスペースです。
- (3) 配置フラグ: 文字列幅が指定された場合、デフォルトは右詰めで、- 記号を追加すると左詰めに変更できます。
- (4) 幅の数値
- (5) 小数桁数/文字列の切り詰め: 幅の数値の後に付ける小数部分 n は、後ろに f(浮動小数点数変換指定子、例: %6.3f)が続く場合はその浮動小数点数の小数部を n 桁だけ保持し、後ろに s(文字列変換指定子、例: %5.3s)が続く場合はその文字列の先頭 n 文字だけを表示します。
例
string2 = "Tutorial"
number1 = 10
number2 = 20
-- 基本的な文字列フォーマット
print(string.format("基本格式化 %s %s",string1,string2))
-- 日付フォーマット
date = 2; month = 1; year = 2014
print(string.format("日期格式化 %02d/%02d/%04d", date, month, year))
-- 10進数フォーマット
print(string.format("%.4f",1/3))
上記のコードを実行した結果は次のとおりです:
基本格式化 Lua Tutorial 日期格式化 02/01/2014 0.3333
他の例:
例
string.format("%+d", 17.0) -- 出力+17
string.format("%05d", 17) -- 出力00017
string.format("%o", 17) -- 出力21
string.format("%u", 3.14) -- 出力3
string.format("%x", 13) -- 出力d
string.format("%X", 13) -- 出力D
string.format("%e", 1000) -- 出力1.000000e+03
string.format("%E", 1000) -- 出力1.000000E+03
string.format("%6.3f", 13) -- 出力13.000
string.format("%q", "One\nTwo") -- 出力"One\
-- Two"
string.format("%s", "monkey") -- 出力monkey
string.format("%10s", "monkey") -- 出力 monkey
string.format("%5.3s", "monkey") -- 出力 mon
文字と整数の相互変換
次の例は、文字と整数の相互変換を示しています:
例
-- 最初の文字を変換
print(string.byte("Lua"))
-- 3番目の文字を変換
print(string.byte("Lua",3))
-- 末尾の最初の文字を変換
print(string.byte("Lua",-1))
-- 2番目の文字
print(string.byte("Lua",2))
-- 末尾の2番目の文字を変換
print(string.byte("Lua",-2))
-- 整数のASCIIコードを文字に変換
print(string.char(97))
上記のコードを実行した結果は次のとおりです:
76 97 97 117 117 a
その他のよく使う関数
次の例では、文字列の長さの計算、文字列の連結、文字列の複製などの他の文字列操作を示しています:
例
string2 = "サンプル"
string3 = ".com"
-- .. を使用した文字列連結
print("连接字符串",string1..string2..string3)
-- 文字列の長さ
print("字符串长度 ",string.len(string2))
-- 文字列を2回複製
repeatedString = string.rep(string2,2)
print(repeatedString)
上記のコードを実行した結果は次のとおりです:
连接字符串 www.example.com 字符串长度 6 サンプルサンプル
パターンマッチング
Lua のパターンは、通常の文字列で直接記述されます。これはパターンマッチ関数で使用されます。string.find, string.gmatch, string.gsub, string.match。
パターン文字列では文字クラスも使用できます。
文字クラスとは、特定の文字集合内の任意の文字にマッチするパターン項目のことです。たとえば、文字クラス%dは任意の数字にマッチします。したがって、パターン文字列%d%d/%d%d/%d%d%d%d検索dd/mm/yyyy形式の日付:
例
date = "%d%d/%d%d/%d%d%d%d"
print(string.sub(s, string.find(s, date))) --> 30/05/1999
次の表は、Lua がサポートするすべての文字クラスを示しています:
単一の文字(^$()%.[]*+-?を除く): その文字自身にマッチします
- .(ドット): 任意の文字にマッチします
- %a: 任意の英字にマッチします
- %c: 任意の制御文字にマッチします(例: \n)
- %d: 任意の数字にマッチします
- %l: 任意の小文字にマッチします
- %p: 任意の句読点(punctuation)にマッチします
- %s: 任意の空白文字にマッチします
- %u: 任意の大文字にマッチします
- %w: 任意の英字/数字にマッチします
- %x: 任意の16進数にマッチします
- %z: 任意の0を表す文字にマッチします
- %x(ここで x は英字でも数字でもない文字): 文字 x にマッチします。主に式内で特別な機能を持つ文字 (^$()%.[]*+-?) とのマッチングを扱うために使います。たとえば %% は % にマッチします。
- [複数の文字クラス]: [] 内に含まれる任意の文字クラスにマッチします。たとえば [%w_] は任意の英字/数字、またはアンダースコア記号 (_) にマッチします。
- [^複数の文字クラス]: [] 内に含まれない任意の文字クラスにマッチします。たとえば [^%s] は任意の非空白文字にマッチします。
上記の文字クラスを大文字で書いた場合、その文字クラス以外の任意の文字にマッチします。たとえば、%S は任意の非空白文字にマッチします。たとえば、'%A' は英字以外の文字です:
> print(string.gsub("hello, up-down!", "%A", "."))
hello..up.down. 4
数字の4は文字列の結果の一部ではなく、gsub が返す2番目の結果であり、置換が発生した回数を表します。
パターンマッチングには特別な意味を持つ特殊文字がいくつかあります。Lua の特殊文字は次のとおりです:
( ) . % + - * ? [ ^ $
'%' は特殊文字のエスケープ文字として使われます。したがって '%.' はドットにマッチし、'%%' は文字 '%' にマッチします。エスケープ文字 '%' は特殊文字のエスケープだけでなく、すべての非英字文字にも使用できます。
パターン項目は次のいずれかです:
- 単一の文字クラス: そのカテゴリ内の任意の単一文字にマッチします;
- 単一の文字クラスと '
**' を続けたもの。ゼロ個以上のそのクラスの文字にマッチします。この項目は常に可能な限り長い文字列にマッチします; - 単一の文字クラスと '
++' を続けたもの。1個以上のそのクラスの文字にマッチします。この項目は常に可能な限り長い文字列にマッチします; - 単一の文字クラスと '
--' を続けたもの。ゼロ個以上のそのクラスの文字にマッチします。'**' とは異なり、この項目は常に可能な限り短い文字列にマッチします; - 単一の文字クラスと '
??' を続けたもの。ゼロ個または1個のそのクラスの文字にマッチします。可能であれば、1個にマッチします; -
%n%n。ここで、nn は1から9まで;nn 番目のキャプチャ(後述)に等しい部分文字列にマッチします。 -
%bxy%bxy。ここで、xとyx と y は2つの明確な文字です; この項目はxx で始まりyy で終わり、 かつその中でxとyx と y がバランスを保つ文字列にマッチします。つまり、この文字列を左から右に読むとき、x を読むたびにx 就 +1y を読み、y 就 -1そして、y最終的に終端にある y は、最初にカウントが 0 になるyy です。%b()たとえば、項目 -
%f[set]%b() は括弧のバランスが取れた式にマッチします。%f[set] は、フロンティア(境界)パターンを指します;この項目は、setset 内の特定の文字の前にある空文字列にマッチし、かつその位置の直前の文字がsetset に属さない場合にマッチします。set集合\0set の意味は前述のとおりです。マッチした空文字列の開始点と終了点は、その場所に文字 '
0' があるものとして計算されます。
パターン:パターン^は、パターン項目の並びです。パターンの先頭に記号 '^' を付けると、文字列の先頭からマッチするように固定されます。パターンの末尾に記号 '$$' を付けると、マッチングが文字列の末尾に固定されます。もし '^^' と '$$' が他の場所に現れた場合、それらは特別な意味を持たず、単にそれ自身を表します。
キャプチャ:
パターン内では、括弧でサブパターンを囲むことができます。これらのサブパターンはキャプチャと呼ばれます。マッチが成功すると、キャプチャによってマッチされた文字列内の部分文字列が、将来の使用のために保存されます。キャプチャは、その左括弧の順序で番号が付けられます。たとえば、パターン"(a*(.)%w(%s*))"(a)b(c) では、文字列内で"a*(.)%w(%s*)"a にマッチした部分が最初のキャプチャに保存されます(したがって番号1)。.b にマッチした文字は2番目のキャプチャで、%s*c にマッチした部分は3番目です。
特別な場合として、空のキャプチャ()は、現在の文字列内の位置(数値)をキャプチャします。たとえば、パターン ()() を"()aa()"文字列 "hello" に適用すると、"flaaap"2つのキャプチャ、3 と 5 が生成されます。