lua開発--文字列,json,符号化変換
23661 ワード
JSONライブラリ
データ転送時のJSON形式は現在広く応用されているため、LuaオブジェクトとJSON文字列間の相互変換は非常に一般的な機能である.現在LuaにもいくつかのJSONライブラリがあり、本人はcjson、dkjsonを使ったことがある.ここでcjsonの文法は厳格で(例えばunicode<20>u 7 eaf)、要求が規範に合致しないと解析に失敗し(例えば<2)、dkjsonは比較的緩やかで、もちろんcjsonのソースコードを修正することによっていくつかの特殊な要求を完成することができます.dkjsonを使用しても性能の問題はなく、現在はdkjsonを使用しています.使用時に特に注意しなければならないのは、ほとんどのJSONライブラリがUTF-8符号化のみをサポートしていることです.したがって、文字コードがGBKのような場合は、まずUTF-8に変換して処理する必要があります.
1.1、test_cjson.lua
nullはcjsonに変換されます.null;循環参照は異常Cannot serialise,excessive nestingを放出し、デフォルトの解析ネスト深さは1000であり、cjsonを通過することができる.encode_max_depth()深さを設定して性能を向上させる;cjsonを使用します.safeは異常を投げ出すのではなくnilに戻る.
1.2、example.confプロファイル
1.3、アクセスhttp://192.168.1.2/lua_cjson以下の結果が得られる
lua-cjsonドキュメントhttp://www.kyne.com.au/~mark/software/lua-cjson-manual.html.
次にdkjsonを勉強します.2.1、dkjsonライブラリのダウンロード
2.2、test_dkjson.lua
デフォルトで解析されたjsonの文字には縮退と改行があり、{indent=true}構成を使用してすべての内容を1行に配置します.cjsonとは異なり、json文字列のnullを解析するとnilが得られます.
2.3、example.confプロファイル
2.4、アクセスhttp://192.168.1.2/lua_dkjson結果{"hobby":["film","music","read","is_male":false,"name":"zhangsan","id":1}nil true film dkjsonドキュメントhttp://dkolf.de/src/dkjson-lua.fsl/homeおよびhttp://dkolf.de/src/dkjson-lua.fsl/wiki?name=Documentation.
コード変換
いくつかのクラスライブラリを使用すると、ほとんどのライブラリはUTF-8符号化のみをサポートしていることがわかります.そのため、他の符号化を使用する場合は、符号化変換の処理が必要です.Linuxで最も一般的なのはiconvであり、lua-iconvはLua APIのパッケージである.
lua-iconvをインストールするには、次の2つの方法があります.
ubuntuでは次のように使用できます.
ソースコードのインストール方式は、gcc環境のダウンロードアドレスが必要です:https://github.com/ittner/lua-iconv/downloads
1、test_iconv.lua
この場合、ファイル符号化はUTF-8でなければならない.すなわち、Luaファイル符号化はなぜ中の文字符号化が何であるのか.2、example.confプロファイル
charsetを通じてブラウザに私たちの文字がgbkに符号化されていることを伝えます.
3、アクセスhttp://192.168.1.2/lua_iconv出力文字化けしが見つかります.
test_iconv.luaの文字はトランスコード処理を行います:
トランスコードにより最終出力のコンテンツをgbkに符号化し、方式iconvを用いる.new(ターゲット符号化、ソース符号化).
次のエラーが発生する可能性があります.
また、実際の使用中にUTF-8からGBKへの変換プロセスを行うと、一部の文字はGBK符号表では変換できないが、この場合、より高い符号化GB 18030を用いて変換を完了することができる.
詳細については、http://ittner.github.io/lua-iconv/.
ビット演算
Lua 5.3以前はビット演算サポートは提供されていなかったが、LuaJITがbitライブラリを提供しているなどのサードパーティライブラリを使用する必要がある.
1、test_bit.lua
lshiftは左シフト演算を行い,すなわち4を得る.
その他のビット操作APIは参照してくださいhttp://bitop.luajit.org/api.html.Lua 5.3のビット演算オペレータhttp://cloudwu.github.io/lua53doc/manual.html#3.4.2.
cache
ngx_luaモジュール自体はグローバル共有メモリngxを提供する.shared.DICTは、グローバル共有を実現することができ、また、Redisのようなキャッシュを実現するために使用することができる.もう1つのlua-resty-lrucacheはngxと実現する.shared.DICTが異なるのは、ワークごとに共有されていることです.つまり、ワークごとにキャッシュが行われ、実際に使用するとngxに及ばないことがわかります.shared.DICT.しかし、その利点は、グローバル構成を必要としないことです.
1、キャッシュモジュールを作成して一度だけ初期化を実現する:
ここでは,モジュールの特性を用いて,ワークごとにcacheインスタンスを1回だけ初期化することを実現した.2、test_lrucache.lua
アクセス量統計などの実装は可能ですが、Workerプロセスあたりのみです.3、example.confプロファイル
アクセスhttp://192.168.1.2/lua_lrucacheテスト.
詳細については、https://github.com/openresty/lua-resty-lrucache.
文字列処理
Lua 5.3以前は文字操作に関する関数を提供していなかった.例えば、文字列の切り取り、置換などはすべてバイト単位で操作された.実際に使用するとき、特に中国語を含むシーンでは、明らかにニーズを満たすことができません.Lua 5.3でも基本的なUTF-8操作のみが提供される.
Lua UTF-8ライブラリ
https://github.com/starwing/luautf8
LuaRocksインストール
ソースコードのインストール
1、test_utf8.lua
ファイル符号化はUTF 8でなければなりません.ここでは、最も一般的な文字列長計算と文字列切り取りを実現します.2、example.confプロファイル
3、訪問http://192.168.1.2/lua_utf8テストは以下の結果を得た.
len:5 sub:abc中
文字列はunicode符号化に変換されます.
上記の方法でutf 8 to unicode:61u 4 e 2 du 6587が出力されます.
これで基本的な文字列操作が完了し、他のluautf 8モジュールのAPIやLuaAPIも参照できます.
http://cloudwu.github.io/lua53doc/manual.html#6.4
http://cloudwu.github.io/lua53doc/manual.html#6.5
また、GBKの操作は、先にUTF-8に変換し、最後にGBKに変換すればよい.
データ転送時のJSON形式は現在広く応用されているため、LuaオブジェクトとJSON文字列間の相互変換は非常に一般的な機能である.現在LuaにもいくつかのJSONライブラリがあり、本人はcjson、dkjsonを使ったことがある.ここでcjsonの文法は厳格で(例えばunicode<20>u 7 eaf)、要求が規範に合致しないと解析に失敗し(例えば<2)、dkjsonは比較的緩やかで、もちろんcjsonのソースコードを修正することによっていくつかの特殊な要求を完成することができます.dkjsonを使用しても性能の問題はなく、現在はdkjsonを使用しています.使用時に特に注意しなければならないのは、ほとんどのJSONライブラリがUTF-8符号化のみをサポートしていることです.したがって、文字コードがGBKのような場合は、まずUTF-8に変換して処理する必要があります.
1.1、test_cjson.lua
local cjson = require("cjson")
--lua
local obj = {
id = 1,
name = "zhangsan",
age = nil,
is_male = false,
hobby = {"film", "music", "read"}
}
local str = cjson.encode(obj)
ngx.say(str, "
")
-- lua
str = '{"hobby":["film","music","read"],"is_male":false,"name":"zhangsan","id":1,"age":null}'
local obj = cjson.decode(str)
ngx.say(obj.age, "
")
ngx.say(obj.age == nil, "
")
ngx.say(obj.age == cjson.null, "
")
ngx.say(obj.hobby[1], "
")
--
obj = {
id = 1
}
obj.obj = obj
-- Cannot serialise, excessive nesting
--ngx.say(cjson.encode(obj), "
")
local cjson_safe = require("cjson.safe")
--nil
ngx.say(cjson_safe.encode(obj), "
")
nullはcjsonに変換されます.null;循環参照は異常Cannot serialise,excessive nestingを放出し、デフォルトの解析ネスト深さは1000であり、cjsonを通過することができる.encode_max_depth()深さを設定して性能を向上させる;cjsonを使用します.safeは異常を投げ出すのではなくnilに戻る.
1.2、example.confプロファイル
location ~ /lua_cjson {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_cjson.lua;
}
1.3、アクセスhttp://192.168.1.2/lua_cjson以下の結果が得られる
{"hobby":["film","music","read"],"is_male":false,"name":"zhangsan","id":1}
null
false
true
film
nil
lua-cjsonドキュメントhttp://www.kyne.com.au/~mark/software/lua-cjson-manual.html.
次にdkjsonを勉強します.2.1、dkjsonライブラリのダウンロード
cd /usr/example/lualib/
wget http://dkolf.de/src/dkjson-lua.fsl/raw/dkjson.lua?name=16cbc26080996d9da827df42cb0844a25518eeb3 -O dkjson.lua
2.2、test_dkjson.lua
local dkjson = require("dkjson")
--lua
local obj = {
id = 1,
name = "zhangsan",
age = nil,
is_male = false,
hobby = {"film", "music", "read"}
}
local str = dkjson.encode(obj, {indent = true})
ngx.say(str, "
")
-- lua
str = '{"hobby":["film","music","read"],"is_male":false,"name":"zhangsan","id":1,"age":null}'
local obj, pos, err = dkjson.decode(str, 1, nil)
ngx.say(obj.age, "
")
ngx.say(obj.age == nil, "
")
ngx.say(obj.hobby[1], "
")
--
obj = {
id = 1
}
obj.obj = obj
--reference cycle
--ngx.say(dkjson.encode(obj), "
")
デフォルトで解析されたjsonの文字には縮退と改行があり、{indent=true}構成を使用してすべての内容を1行に配置します.cjsonとは異なり、json文字列のnullを解析するとnilが得られます.
2.3、example.confプロファイル
location ~ /lua_dkjson {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_dkjson.lua;
}
2.4、アクセスhttp://192.168.1.2/lua_dkjson結果{"hobby":["film","music","read","is_male":false,"name":"zhangsan","id":1}nil true film dkjsonドキュメントhttp://dkolf.de/src/dkjson-lua.fsl/homeおよびhttp://dkolf.de/src/dkjson-lua.fsl/wiki?name=Documentation.
コード変換
いくつかのクラスライブラリを使用すると、ほとんどのライブラリはUTF-8符号化のみをサポートしていることがわかります.そのため、他の符号化を使用する場合は、符号化変換の処理が必要です.Linuxで最も一般的なのはiconvであり、lua-iconvはLua APIのパッケージである.
lua-iconvをインストールするには、次の2つの方法があります.
ubuntuでは次のように使用できます.
apt-get install luarocks
luarocks install lua-iconv
cp /usr/local/lib/lua/5.1/iconv.so /usr/example/lualib/
ソースコードのインストール方式は、gcc環境のダウンロードアドレスが必要です:https://github.com/ittner/lua-iconv/downloads
wget https://github.com/do^Cloads/ittner/lua-iconv/lua-iconv-7.tar.gz
tar -xvf lua-iconv-7.tar.gz
cd lua-iconv-7
gcc -O2 -fPIC -I/usr/include/lua5.1 -c luaiconv.c -o luaiconv.o -I/usr/include
gcc -shared -o iconv.so -L/usr/local/lib luaiconv.o -L/usr/lib
cp iconv.so /usr/example/lualib/
1、test_iconv.lua
ngx.say(" ")
この場合、ファイル符号化はUTF-8でなければならない.すなわち、Luaファイル符号化はなぜ中の文字符号化が何であるのか.2、example.confプロファイル
location ~ /lua_iconv {
default_type 'text/html';
charset gbk;
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_iconv.lua;
}
charsetを通じてブラウザに私たちの文字がgbkに符号化されていることを伝えます.
3、アクセスhttp://192.168.1.2/lua_iconv出力文字化けしが見つかります.
test_iconv.luaの文字はトランスコード処理を行います:
local iconv = require("iconv")
local togbk = iconv.new("gbk", "utf-8")
local str, err = togbk:iconv(" ")
ngx.say(str)
トランスコードにより最終出力のコンテンツをgbkに符号化し、方式iconvを用いる.new(ターゲット符号化、ソース符号化).
次のエラーが発生する可能性があります.
nil
。
iconv.ERROR_NO_MEMORY
。
iconv.ERROR_INVALID
。
iconv.ERROR_INCOMPLETE
。
iconv.ERROR_FINALIZED
, 。
iconv.ERROR_UNKNOWN
また、実際の使用中にUTF-8からGBKへの変換プロセスを行うと、一部の文字はGBK符号表では変換できないが、この場合、より高い符号化GB 18030を用いて変換を完了することができる.
詳細については、http://ittner.github.io/lua-iconv/.
ビット演算
Lua 5.3以前はビット演算サポートは提供されていなかったが、LuaJITがbitライブラリを提供しているなどのサードパーティライブラリを使用する必要がある.
1、test_bit.lua
local bit = require("bit")
ngx.say(bit.lshift(1, 2))
lshiftは左シフト演算を行い,すなわち4を得る.
その他のビット操作APIは参照してくださいhttp://bitop.luajit.org/api.html.Lua 5.3のビット演算オペレータhttp://cloudwu.github.io/lua53doc/manual.html#3.4.2.
cache
ngx_luaモジュール自体はグローバル共有メモリngxを提供する.shared.DICTは、グローバル共有を実現することができ、また、Redisのようなキャッシュを実現するために使用することができる.もう1つのlua-resty-lrucacheはngxと実現する.shared.DICTが異なるのは、ワークごとに共有されていることです.つまり、ワークごとにキャッシュが行われ、実際に使用するとngxに及ばないことがわかります.shared.DICT.しかし、その利点は、グローバル構成を必要としないことです.
1、キャッシュモジュールを作成して一度だけ初期化を実現する:
vim /usr/example/lualib/mycache.lua
local lrucache = require("resty.lrucache")
-- ,
local cache, err = lrucache.new(200)
if not cache then
ngx.log(ngx.ERR, "create cache error : ", err)
end
local function set(key, value, ttlInSeconds)
cache:set(key, value, ttlInSeconds)
end
local function get(key)
return cache:get(key)
end
local _M = {
set = set,
get = get
}
return _M
ここでは,モジュールの特性を用いて,ワークごとにcacheインスタンスを1回だけ初期化することを実現した.2、test_lrucache.lua
local mycache = require("mycache")
local count = mycache.get("count") or 0
count = count + 1
mycache.set("count", count, 10 * 60 * 60) --10
ngx.say(mycache.get("count"))
アクセス量統計などの実装は可能ですが、Workerプロセスあたりのみです.3、example.confプロファイル
location ~ /lua_lrucache {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_lrucache.lua;
}
アクセスhttp://192.168.1.2/lua_lrucacheテスト.
詳細については、https://github.com/openresty/lua-resty-lrucache.
文字列処理
Lua 5.3以前は文字操作に関する関数を提供していなかった.例えば、文字列の切り取り、置換などはすべてバイト単位で操作された.実際に使用するとき、特に中国語を含むシーンでは、明らかにニーズを満たすことができません.Lua 5.3でも基本的なUTF-8操作のみが提供される.
Lua UTF-8ライブラリ
https://github.com/starwing/luautf8
LuaRocksインストール
# git
apt-get install git
luarocks install utf8
cp /usr/local/lib/lua/5.1/utf8.so /usr/example/lualib/
ソースコードのインストール
wget https://github.com/starwing/luautf8/archive/master.zip
unzip master.zip
cd luautf8-master/
gcc -O2 -fPIC -I/usr/include/lua5.1 -c utf8.c -o utf8.o -I/usr/include
gcc -shared -o utf8.so -L/usr/local/lib utf8.o -L/usr/lib
1、test_utf8.lua
local utf8 = require("utf8")
local str = "abc "
ngx.say("len : ", utf8.len(str), "
")
ngx.say("sub : ", utf8.sub(str, 1, 4))
ファイル符号化はUTF 8でなければなりません.ここでは、最も一般的な文字列長計算と文字列切り取りを実現します.2、example.confプロファイル
location ~ /lua_utf8 {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/example/lua/test_utf8.lua;
}
3、訪問http://192.168.1.2/lua_utf8テストは以下の結果を得た.
len:5 sub:abc中
文字列はunicode符号化に変換されます.
local bit = require("bit")
local bit_band = bit.band
local bit_bor = bit.bor
local bit_lshift = bit.lshift
local string_format = string.format
local string_byte = string.byte
local table_concat = table.concat
local function utf8_to_unicode(str)
if not str or str == "" or str == ngx.null then
return nil
end
local res, seq, val = {}, 0, nil
for i = 1, #str do
local c = string_byte(str, i)
if seq == 0 then
if val then
res[#res + 1] = string_format("%04x", val)
end
seq = c < 0x80 and 1 or c < 0xE0 and 2 or c < 0xF0 and 3 or
c < 0xF8 and 4 or --c < 0xFC and 5 or c < 0xFE and 6 or
0
if seq == 0 then
ngx.log(ngx.ERR, 'invalid UTF-8 character sequence' .. ",,," .. tostring(str))
return str
end
val = bit_band(c, 2 ^ (8 - seq) - 1)
else
val = bit_bor(bit_lshift(val, 6), bit_band(c, 0x3F))
end
seq = seq - 1
end
if val then
res[#res + 1] = string_format("%04x", val)
end
if #res == 0 then
return str
end
return "\\u" .. table_concat(res, "\\u")
end
ngx.say("utf8 to unicode : ", utf8_to_unicode("abc "), "
")
上記の方法でutf 8 to unicode:61u 4 e 2 du 6587が出力されます.
これで基本的な文字列操作が完了し、他のluautf 8モジュールのAPIやLuaAPIも参照できます.
http://cloudwu.github.io/lua53doc/manual.html#6.4
http://cloudwu.github.io/lua53doc/manual.html#6.5
また、GBKの操作は、先にUTF-8に変換し、最後にGBKに変換すればよい.