鍍金池/ 教程/ Java/ String 庫
定時任務(wù)
函數(shù)的參數(shù)
超時
一個 openresty 內(nèi)存“泄漏”問題
獲取 uri 參數(shù)
局部變量
sleep
灰度發(fā)布
TIME_WAIT
代碼覆蓋率
連接池
CentOS 平臺安裝
稀疏數(shù)組
如何只啟動一個 timer 工作?
變量的共享范圍
break,return 關(guān)鍵字
Nginx
SQL 注入
如何引用第三方 resty 庫
不同階段共享變量
獲取請求 body
動態(tài)生成的 lua-resty-redis 模塊方法
動態(tài)加載證書和 OCSP stapling
repeat 控制結(jié)構(gòu)
編碼為 array 還是 object
Nginx 靜態(tài)文件服務(wù)
執(zhí)行階段概念
Lua 函數(shù)
日期時間函數(shù)
健康監(jiān)測
與其他 location 配合
for 控制結(jié)構(gòu)
函數(shù)定義
HTTPS 時代
點號與冒號操作符的區(qū)別
String 庫
文件操作
OpenResty 最佳實踐
<code>ngx.shared.DICT</code> 非隊列性質(zhì)
使用動態(tài) DNS 來完成 HTTP 請求
代碼規(guī)范
什么是 JIT?
Windows 平臺安裝
正確的記錄日志
LuaNginxModule
不用標(biāo)準(zhǔn)庫
C10K 編程
控制結(jié)構(gòu)
請求中斷后的處理
Lua 環(huán)境搭建
Test::Nginx 能指定現(xiàn)成的 nginx.conf,而不是自動生成一個嗎
Lua 基礎(chǔ)數(shù)據(jù)類型
動態(tài)限速
PostgresNginxModule
簡單API Server框架
API 測試
location 匹配規(guī)則
虛變量
單元測試
防止 SQL 注入
select + set_keepalive 組合操作引起的數(shù)據(jù)讀寫錯誤
阻塞操作
全動態(tài)函數(shù)調(diào)用
Web 服務(wù)
典型應(yīng)用場景
Nginx 新手起步
TLS session resumption
輸出響應(yīng)體
調(diào)用代碼前先定義函數(shù)
module 是邪惡的
怎樣理解 cosocket
模塊
Socket 編程發(fā)展
如何對 Nginx Lua module 添加新 api
如何在后臺開啟輕量級線程完成定時任務(wù)?
如何定位問題
table 庫
json 解析的異常捕獲
如何安裝火焰圖生成工具
lua 中如何 continue
if 是邪惡的
為什么我們的域名不能被解析
抵制使用 module() 定義模塊
測試
body 在 location 中的傳遞
Lua 入門
子查詢
pipeline 壓縮請求數(shù)量
如何發(fā)起新 HTTP 請求
Lua 簡介
緩存失效風(fēng)暴
Ubuntu 平臺安裝
日志輸出
緩存
Lua 面向?qū)ο缶幊?/span>
Nginx 陷阱和常見錯誤
Redis 接口的二次封裝(發(fā)布訂閱)
日志
訪問有授權(quán)驗證的 Redis
正則表達式
lock
熱裝載代碼
調(diào)用 FFI 出現(xiàn) &quot;table overflow&quot;
數(shù)據(jù)合法性檢測
禁止某些終端訪問
控制結(jié)構(gòu) if-else
調(diào)試
與 Docker 使用的網(wǎng)絡(luò)瓶頸
PostgresNginxModule 模塊的調(diào)用方式
用 do-end 整理你的代碼
FFI
什么時候使用
簡介
環(huán)境搭建
Mac OS X 平臺安裝
火焰圖
負(fù)載均衡
while 型控制結(jié)構(gòu)
如何定位 openresty 崩潰 bug
使用 Nginx 內(nèi)置綁定變量
判斷數(shù)組大小
請求返回后繼續(xù)執(zhí)行
Redis 接口的二次封裝
KeepAlive
反向代理
協(xié)議無痛升級
數(shù)學(xué)庫
元表
Vanilla 介紹
HelloWorld
LuaCjsonLibrary
持續(xù)集成
代碼靜態(tài)分析
網(wǎng)上有大量對 Lua 調(diào)優(yōu)的推薦,我們應(yīng)該如何看待?
script 壓縮復(fù)雜請求
非空判斷
性能測試
函數(shù)返回值
API 的設(shè)計
kong 介紹
表達式
不支持事務(wù)
LuaRestyDNSLibrary 簡介

String 庫

Lua 字符串庫包含很多強大的字符操作函數(shù)。字符串庫中的所有函數(shù)都導(dǎo)出在模塊 string 中。在 Lua 5.1 中,它還將這些函數(shù)導(dǎo)出作為 string 類型的方法。這樣假設(shè)要返回一個字符串轉(zhuǎn)的大寫形式,可以寫成 ans = string.upper(s) , 也能寫成 ans = s:upper()。為了避免與之前版本不兼容,此處使用前者。

Lua 字符串總是由字節(jié)構(gòu)成的。Lua 核心并不嘗試?yán)斫饩唧w的字符集編碼(比如 GBK 和 UTF-8 這樣的多字節(jié)字符編碼)。

需要特別注意的一點是,Lua 字符串內(nèi)部用來標(biāo)識各個組成字節(jié)的下標(biāo)是從 1 開始的,這不同于像 C 和 Perl 這樣的編程語言。這樣數(shù)字符串位置的時候再也不用調(diào)整,對于非專業(yè)的開發(fā)者來說可能也是一個好事情,string.sub(str, 3, 7) 直接表示從第三個字符開始到第七個字符(含)為止的子串。

string.byte(s [, i [, j ]])

返回字符 s[i]、s[i + 1]、s[i + 2]、······、s[j] 所對應(yīng)的 ASCII 碼。i 的默認(rèn)值為 1,即第一個字節(jié),j 的默認(rèn)值為 i 。

示例代碼

print(string.byte("abc", 1, 3))
print(string.byte("abc", 3)) -- 缺少第三個參數(shù),第三個參數(shù)默認(rèn)與第二個相同,此時為 3
print(string.byte("abc"))    -- 缺少第二個和第三個參數(shù),此時這兩個參數(shù)都默認(rèn)為 1

-->output
97  98  99
99
97

由于 string.byte 只返回整數(shù),而并不像 string.sub 等函數(shù)那樣(嘗試)創(chuàng)建新的 Lua 字符串, 因此使用 string.byte 來進行字符串相關(guān)的掃描和分析是最為高效的,尤其是在被 LuaJIT 2 所 JIT 編譯之后。

string.char (...)

接收 0 個或更多的整數(shù)(整數(shù)范圍:0~255),返回這些整數(shù)所對應(yīng)的 ASCII 碼字符組成的字符串。當(dāng)參數(shù)為空時,默認(rèn)是一個 0。

示例代碼

print(string.char(96, 97, 98))
print(string.char())        -- 參數(shù)為空,默認(rèn)是一個0,
                            -- 你可以用string.byte(string.char())測試一下
print(string.char(65, 66))

--> output
`ab

AB

此函數(shù)特別適合從具體的字節(jié)構(gòu)造出二進制字符串。這經(jīng)常比使用 table.concat 函數(shù)和 .. 連接運算符更加高效。

string.upper(s)

接收一個字符串 s,返回一個把所有小寫字母變成大寫字母的字符串。

示例代碼

print(string.upper("Hello Lua"))  -->output  HELLO LUA

string.lower(s)

接收一個字符串 s,返回一個把所有大寫字母變成小寫字母的字符串。

示例代碼

print(string.lower("Hello Lua"))  -->output   hello lua

string.len(s)

接收一個字符串,返回它的長度。

示例代碼

print(string.len("hello lua")) -->output  9

使用此函數(shù)是不推薦的。應(yīng)當(dāng)總是使用 # 運算符來獲取 Lua 字符串的長度。

由于 Lua 字符串的長度是專門存放的,并不需要像 C 字符串那樣即時計算,因此獲取字符串長度的操作總是 O(1) 的時間復(fù)雜度。

string.find(s, p [, init [, plain]])

在 s 字符串中第一次匹配 p 字符串。若匹配成功,則返回 p 字符串在 s 字符串中出現(xiàn)的開始位置和結(jié)束位置;若匹配失敗,則返回 nil。 第三個參數(shù) init 默認(rèn)為 1,并且可以為負(fù)整數(shù),當(dāng) init 為負(fù)數(shù)時,表示從 s 字符串的 string.len(s) + init 索引處開始向后匹配字符串 p 。 第四個參數(shù)默認(rèn)為 false,當(dāng)其為 true 時,只會把 p 看成一個字符串對待。

示例代碼

local find = string.find
print(find("abc cba", "ab"))
print(find("abc cba", "ab", 2))     -- 從索引為2的位置開始匹配字符串:ab
print(find("abc cba", "ba", -1))    -- 從索引為7的位置開始匹配字符串:ba
print(find("abc cba", "ba", -3))    -- 從索引為6的位置開始匹配字符串:ba
print(find("abc cba", "(%a+)", 1))  -- 從索引為1處匹配最長連續(xù)且只含字母的字符串
print(find("abc cba", "(%a+)", 1, true)) --從索引為1的位置開始匹配字符串:(%a+)

-->output
1   2
nil
nil
6   7
1   3   abc
nil

對于 LuaJIT 這里有個性能優(yōu)化點,對于 string.find 方法,當(dāng)只有字符串查找匹配時,是可以被 JIT 編譯器優(yōu)化的,有關(guān) JIT 可以編譯優(yōu)化清單,大家可以參考 http://wiki.luajit.org/NYI,性能提升是非常明顯的,通常是 100 倍量級。這里有個的例子,大家可以參考 https://groups.google.com/forum/m/#!topic/openresty-en/rwS88FGRsUI。

string.format(formatstring, ...)

按照格式化參數(shù) formatstring,返回后面 ... 內(nèi)容的格式化版本。編寫格式化字符串的規(guī)則與標(biāo)準(zhǔn) c 語言中 printf 函數(shù)的規(guī)則基本相同:它由常規(guī)文本和指示組成,這些指示控制了每個參數(shù)應(yīng)放到格式化結(jié)果的什么位置,及如何放入它們。一個指示由字符 % 加上一個字母組成,這些字母指定了如何格式化參數(shù),例如 d 用于十進制數(shù)、x 用于十六進制數(shù)、o 用于八進制數(shù)、f 用于浮點數(shù)、s 用于字符串等。在字符 % 和字母之間可以再指定一些其他選項,用于控制格式的細(xì)節(jié)。

示例代碼

print(string.format("%.4f", 3.1415926))     -- 保留4位小數(shù)
print(string.format("%d %x %o", 31, 31, 31))-- 十進制數(shù)31轉(zhuǎn)換成不同進制
d = 29; m = 7; y = 2015                     -- 一行包含幾個語句,用;分開
print(string.format("%s %02d/%02d/%d", "today is:", d, m, y))

-->output
3.1416
31 1f 37
today is: 29/07/2015

string.match(s, p [, init])

在字符串 s 中匹配(模式)字符串 p,若匹配成功,則返回目標(biāo)字符串中與模式匹配的子串;否則返回 nil。第三個參數(shù) init 默認(rèn)為 1,并且可以為負(fù)整數(shù),當(dāng) init 為負(fù)數(shù)時,表示從 s 字符串的 string.len(s) + init 索引處開始向后匹配字符串 p。

示例代碼

print(string.match("hello lua", "lua"))
print(string.match("lua lua", "lua", 2))  --匹配后面那個lua
print(string.match("lua lua", "hello"))
print(string.match("today is 27/7/2015", "%d+/%d+/%d+"))

-->output
lua
lua
nil
27/7/2015

string.match 目前并不能被 JIT 編譯,應(yīng) 盡量 使用 ngx_lua 模塊提供的 ngx.re.match 等接口。

string.gmatch(s, p)

返回一個迭代器函數(shù),通過這個迭代器函數(shù)可以遍歷到在字符串 s 中出現(xiàn)模式串 p 的所有地方。

示例代碼

s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do  --匹配最長連續(xù)且只含字母的字符串
    print(w)
end

-->output
hello
world
from
Lua

t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%a+)=(%a+)") do  --匹配兩個最長連續(xù)且只含字母的
    t[k] = v                                    --字符串,它們之間用等號連接
end
for k, v in pairs(t) do
print (k,v)
end

-->output
to      Lua
from    world

此函數(shù)目前并不能被 LuaJIT 所 JIT 編譯,而只能被解釋執(zhí)行。應(yīng) 盡量 使用 ngx_lua 模塊提供的 ngx.re.gmatch 等接口。

string.rep(s, n)

返回字符串 s 的 n 次拷貝。

示例代碼

print(string.rep("abc", 3)) --拷貝3次"abc"

-->output  abcabcabc

string.sub(s, i [, j])

返回字符串 s 中,索引 i 到索引 j 之間的子字符串。當(dāng) j 缺省時,默認(rèn)為 -1,也就是字符串 s 的最后位置。i 可以為負(fù)數(shù)。當(dāng)索引 i 在字符串 s 的位置在索引 j 的后面時,將返回一個空字符串。

示例代碼

print(string.sub("Hello Lua", 4, 7))
print(string.sub("Hello Lua", 2))
print(string.sub("Hello Lua", 2, 1))    --看到返回什么了嗎
print(string.sub("Hello Lua", -3, -1))

-->output
lo L
ello Lua

Lua

如果你只是想對字符串中的單個字節(jié)進行檢查,使用 string.char 函數(shù)通常會更為高效。

string.gsub(s, p, r [, n])

將目標(biāo)字符串 s 中所有的子串 p 替換成字符串 r??蛇x參數(shù) n,表示限制替換次數(shù)。返回值有兩個,第一個是被替換后的字符串,第二個是替換了多少次。

示例代碼

print(string.gsub("Lua Lua Lua", "Lua", "hello"))
print(string.gsub("Lua Lua Lua", "Lua", "hello", 2)) --指明第四個參數(shù)

-->output
hello hello hello   3
hello hello Lua     2

此函數(shù)不能為 LuaJIT 所 JIT 編譯,而只能被解釋執(zhí)行。一般我們推薦使用 ngx_lua 模塊提供的 ngx.re.gsub 函數(shù)。

string.reverse (s)

接收一個字符串 s,返回這個字符串的反轉(zhuǎn)。

示例代碼

print(string.reverse("Hello Lua"))  --> output: auL olleH
上一篇:元表下一篇:阻塞操作