日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

第五章 常用Lua开发库2-JSON库、编码转换、字符串处理

發(fā)布時間:2024/9/20 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第五章 常用Lua开发库2-JSON库、编码转换、字符串处理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JSON庫

?

在進(jìn)行數(shù)據(jù)傳輸時JSON格式目前應(yīng)用廣泛,因此從Lua對象與JSON字符串之間相互轉(zhuǎn)換是一個非常常見的功能;目前Lua也有幾個JSON庫,本人用過cjson、dkjson。其中cjson的語法嚴(yán)格(比如unicode \u0020\u7eaf),要求符合規(guī)范否則會解析失敗(如\u002),而dkjson相對寬松,當(dāng)然也可以通過修改cjson的源碼來完成一些特殊要求。而在使用dkjson時也沒有遇到性能問題,目前使用的就是dkjson。使用時要特別注意的是大部分JSON庫都僅支持UTF-8編碼;因此如果你的字符編碼是如GBK則需要先轉(zhuǎn)換為UTF-8然后進(jìn)行處理。

1.1、test_cjson.lua

Java代碼??
  • 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,?"<br/>")??
  • ??
  • --字符串到lua對象??
  • str?=?'{"hobby":["film","music","read"],"is_male":false,"name":"zhangsan","id":1,"age":null}'??
  • local?obj?=?cjson.decode(str)??
  • ??
  • ngx.say(obj.age,?"<br/>")??
  • ngx.say(obj.age?==?nil,?"<br/>")??
  • ngx.say(obj.age?==?cjson.null,?"<br/>")??
  • ngx.say(obj.hobby[1],?"<br/>")??
  • ??
  • ??
  • --循環(huán)引用??
  • obj?=?{??
  • ???id?=?1??
  • }??
  • obj.obj?=?obj??
  • --?Cannot?serialise,?excessive?nesting??
  • --ngx.say(cjson.encode(obj),?"<br/>")??
  • local?cjson_safe?=?require("cjson.safe")??
  • --nil??
  • ngx.say(cjson_safe.encode(obj),?"<br/>")??
  • null將會轉(zhuǎn)換為cjson.null;循環(huán)引用會拋出異常Cannot serialise, excessive nesting,默認(rèn)解析嵌套深度是1000,可以通過cjson.encode_max_depth()設(shè)置深度提高性能;使用cjson.safe不會拋出異常而是返回nil。?

    ?

    1.2、example.conf配置文件

    Java代碼??
  • 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將得到如下結(jié)果

    Java代碼??
  • {"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。

    ?

    接下來學(xué)習(xí)下dkjson。

    ?

    2.1、下載dkjson庫?

    Java代碼??
  • 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

    Java代碼??
  • 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,?"<br/>")??
  • ??
  • --字符串到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,?"<br/>")??
  • ngx.say(obj.age?==?nil,?"<br/>")??
  • ngx.say(obj.hobby[1],?"<br/>")??
  • ??
  • --循環(huán)引用??
  • obj?=?{??
  • ???id?=?1??
  • }??
  • obj.obj?=?obj??
  • --reference?cycle??
  • --ngx.say(dkjson.encode(obj),?"<br/>")???????????????????????????????????????
  • 默認(rèn)情況下解析的json的字符會有縮排和換行,使用{indent = true}配置將把所有內(nèi)容放在一行。和cjson不同的是解析json字符串中的null時會得到nil。??

    2.3、example.conf配置文件

    Java代碼??
  • 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將得到如下結(jié)果

    Java代碼??
  • {?"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。

    ?

    編碼轉(zhuǎn)換

    我們在使用一些類庫時會發(fā)現(xiàn)大部分庫僅支持UTF-8編碼,因此如果使用其他編碼的話就需要進(jìn)行編碼轉(zhuǎn)換的處理;而Linux上最常見的就是iconv,而lua-iconv就是它的一個Lua API的封裝。

    ?

    安裝lua-iconv可以通過如下兩種方式:

    ubuntu下可以使用如下方式

    Java代碼??
  • apt-get?install?luarocks??
  • luarocks?install?lua-iconv???
  • cp?/usr/local/lib/lua/5.1/iconv.so??/usr/example/lualib/??
  • 源碼安裝方式,需要有g(shù)cc環(huán)境

    Java代碼??
  • 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

    Java代碼??
  • ngx.say("中文")??
  • 此時文件編碼必須為UTF-8,即Lua文件編碼為什么里邊的字符編碼就是什么。

    ??

    2、example.conf配置文件

    Java代碼??
  • 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會發(fā)現(xiàn)輸出亂碼;

    ?

    此時需要我們將test_iconv.lua中的字符進(jìn)行轉(zhuǎn)碼處理:

    Java代碼??
  • local?iconv?=?require("iconv")??
  • local?togbk?=?iconv.new("gbk",?"utf-8")??
  • local?str,?err?=?togbk:iconv("中文")??
  • ngx.say(str)??
  • 通過轉(zhuǎn)碼我們得到最終輸出的內(nèi)容編碼為gbk, 使用方式iconv.new(目標(biāo)編碼, 源編碼)。

    ?

    有如下可能出現(xiàn)的錯誤:

    Java代碼??
  • nil?????
  • ????沒有錯誤成功。??
  • iconv.ERROR_NO_MEMORY??
  • ????內(nèi)存不足。??
  • iconv.ERROR_INVALID??
  • ????有非法字符。??
  • iconv.ERROR_INCOMPLETE??
  • ????有不完整字符。??
  • iconv.ERROR_FINALIZED??
  • ????使用已經(jīng)銷毀的轉(zhuǎn)換器,比如垃圾回收了。??
  • iconv.ERROR_UNKNOWN???
  • ????未知錯誤??
  • ?

    iconv在轉(zhuǎn)換時遇到非法字符或不能轉(zhuǎn)換的字符就會失敗,此時可以使用如下方式忽略轉(zhuǎn)換失敗的字符

    Java代碼??
  • local?togbk_ignore?=?iconv.new("GBK//IGNORE",?"UTF-8")??
  • ?

    另外在實際使用中進(jìn)行UTF-8到GBK轉(zhuǎn)換過程時,會發(fā)現(xiàn)有些字符在GBK編碼表但是轉(zhuǎn)換不了,此時可以使用更高的編碼GB18030來完成轉(zhuǎn)換。?

    ?

    更多介紹請參考http://ittner.github.io/lua-iconv/。

    ?

    位運算

    Lua 5.3之前是沒有提供位運算支持的,需要使用第三方庫,比如LuaJIT提供了bit庫。

    1、test_bit.lua?

    Java代碼??
  • local?bit?=?require("bit")??
  • ngx.say(bit.lshift(1,?2))??
  • lshift進(jìn)行左移位運算,即得到4。

    ??

    其他位操作API請參考http://bitop.luajit.org/api.html。Lua 5.3的位運算操作符http://cloudwu.github.io/lua53doc/manual.html#3.4.2.?

    ?

    cache

    ngx_lua模塊本身提供了全局共享內(nèi)存ngx.shared.DICT可以實現(xiàn)全局共享,另外可以使用如Redis來實現(xiàn)緩存。另外還一個lua-resty-lrucache實現(xiàn),其和ngx.shared.DICT不一樣的是它是每Worker進(jìn)程共享,即每個Worker進(jìn)行會有一份緩存,而且經(jīng)過實際使用發(fā)現(xiàn)其性能不如ngx.shared.DICT。但是其好處就是不需要進(jìn)行全局配置。

    ?

    1、創(chuàng)建緩存模塊來實現(xiàn)只初始化一次:

    Java代碼??
  • vim?/usr/example/lualib/mycache.lua???
  • Java代碼??
  • local?lrucache?=?require("resty.lrucache")??
  • --創(chuàng)建緩存實例,并指定最多緩存多少條目??
  • 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??
  • 此處利用了模塊的特性實現(xiàn)了每個Worker進(jìn)行只初始化一次cache實例。

    ?

    2、test_lrucache.lua ?

    Java代碼??
  • 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"))????????????????
  • 可以實現(xiàn)諸如訪問量統(tǒng)計,但僅是每Worker進(jìn)程的。???

    ?

    3、example.conf配置文件

    Java代碼??
  • 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之前沒有提供字符操作相關(guān)的函數(shù),如字符串截取、替換等都是字節(jié)為單位操作;在實際使用時尤其包含中文的場景下顯然不能滿足需求;即使Lua 5.3也僅提供了基本的UTF-8操作。

    ?

    Lua UTF-8庫

    https://github.com/starwing/luautf8

    ?

    LuaRocks安裝

    Java代碼??
  • #首先確保git安裝了??
  • apt-get?install?git??
  • luarocks?install?utf8??
  • cp?/usr/local/lib/lua/5.1/utf8.so??/usr/example/lualib/??
  • ?

    源碼安裝

    Java代碼??
  • 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

    Java代碼??
  • local?utf8?=?require("utf8")??
  • local?str?=?"abc中文"??
  • ngx.say("len?:?",?utf8.len(str),?"<br/>")??
  • ngx.say("sub?:?",?utf8.sub(str,?1,?4))??
  • 文件編碼必須為UTF8,此處我們實現(xiàn)了最常用的字符串長度計算和字符串截取。 2、example.conf配置文件 Java代碼??
  • 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測試得到如下結(jié)果

    len : 5
    sub : abc中

    ?

    字符串轉(zhuǎn)換為unicode編碼:

    Java代碼??
  • 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中文"),?"<br/>")??
  • 如上方法將輸出utf8 to unicode : \u0061\u0062\u0063\u4e2d\u6587。

    ?

    刪除空格:

    Java代碼??
  • local?function?ltrim(s)??
  • ????if?not?s?then??
  • ????????return?s??
  • ????end??
  • ????local?res?=?s??
  • ????local?tmp?=?string_find(res,?'%S')??
  • ????if?not?tmp?then??
  • ????????res?=?''??
  • ????elseif?tmp?~=?1?then??
  • ????????res?=?string_sub(res,?tmp)??
  • ????end??
  • ????return?res??
  • end??
  • ??
  • local?function?rtrim(s)??
  • ????if?not?s?then??
  • ????????return?s??
  • ????end??
  • ????local?res?=?s??
  • ????local?tmp?=?string_find(res,?'%S%s*$')??
  • ????if?not?tmp?then??
  • ????????res?=?''??
  • ????elseif?tmp?~=?#res?then??
  • ????????res?=?string_sub(res,?1,?tmp)??
  • ????end??
  • ??
  • ????return?res??
  • end??
  • ??
  • local?function?trim(s)??
  • ????if?not?s?then??
  • ????????return?s??
  • ????end??
  • ????local?res1?=?ltrim(s)??
  • ????local?res2?=?rtrim(res1)??
  • ????return?res2??
  • end??
  • ?

    字符串分割:

    Java代碼??
  • function?split(szFullString,?szSeparator)??
  • ????local?nFindStartIndex?=?1??
  • ????local?nSplitIndex?=?1??
  • ????local?nSplitArray?=?{}??
  • ????while?true?do??
  • ???????local?nFindLastIndex?=?string.find(szFullString,?szSeparator,?nFindStartIndex)??
  • ???????if?not?nFindLastIndex?then??
  • ????????nSplitArray[nSplitIndex]?=?string.sub(szFullString,?nFindStartIndex,?string.len(szFullString))??
  • ????????break??
  • ???????end??
  • ???????nSplitArray[nSplitIndex]?=?string.sub(szFullString,?nFindStartIndex,?nFindLastIndex?-?1)??
  • ???????nFindStartIndex?=?nFindLastIndex?+?string.len(szSeparator)??
  • ???????nSplitIndex?=?nSplitIndex?+?1??
  • ????end??
  • ????return?nSplitArray??
  • end??
  • 如split("a,b,c", ",") 將得到一個分割后的table。

    ?

    到此基本的字符串操作就完成了,其他luautf8模塊的API和LuaAPI類似可以參考

    http://cloudwu.github.io/lua53doc/manual.html#6.4

    http://cloudwu.github.io/lua53doc/manual.html#6.5

    ?

    另外對于GBK的操作,可以先轉(zhuǎn)換為UTF-8,最后再轉(zhuǎn)換為GBK即可。


    來源:http://jinnianshilongnian.iteye.com/blog/2187643

    總結(jié)

    以上是生活随笔為你收集整理的第五章 常用Lua开发库2-JSON库、编码转换、字符串处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。