Lua字符串庫(整理)

Lua字符串庫小集

1. 基礎字符串函數:
    字符串庫中有一些函數很是簡單,如:
    1). string.len(s) 返回字符串s的長度;
    2). string.rep(s,n) 返回字符串s重複n次的結果;
    3). string.lower(s) 返回s的副本,其中全部的大寫都被轉換爲了小寫形式,其餘字符不變;
    4). string.upper(s) 和lower相反,將小寫轉換爲大寫;
    5). string.sub(s,i,j) 提取字符串s的第i個到第j個字符。Lua中,第一個字符的索引值爲1,最後一個爲-1,以此類推,如:
    print(string.sub("[hello world]",2,-2))      --輸出hello world
    6). string.format(s,...) 返回格式化後的字符串,其格式化規則等同於C語言中printf函數,如:
    print(string.format("pi = %.4f",math.pi)) --輸出pi = 3.1416
    7). string.char(...) 參數爲0到多個整數,並將每一個整數轉換爲對應的字符。而後返回一個由這些字符鏈接而成的字符串,如:
    print(string.char(97,98,99)) --輸出abc
    8). string.byte(s,i) 返回字符串s的第i個字符的Ascii值,若是沒有第二個參數,缺省返回第一個字符的Ascii值。
    print(string.byte("abc"))      --輸出97
    print(string.byte("abc",-1))  --輸出99
    因爲字符串類型的變量都是不可變類型的變量,所以在全部和string相關的函數中,都沒法改變參數中的字符串值,而是生成一個新值返回。

    2. 模式匹配函數:
    Lua的字符串庫提供了一組強大的模式匹配函數,如find、match、gsub和gmatch。
    1). string.find函數:
    在目標字符串中搜索一個模式,若是找到,則返回匹配的起始索引和結束索引,不然返回nil。如:html

1 s = "hello world"
2 i, j = string.find(s,"hello")  
3 print(i, j)        --輸出1  5
4 i, j = string.find(s,"l")
5 print(i, j)        --輸出3  3
6 print(string.find(s,"lll"))  --輸出nil

string.find函數還有一個可選參數,它是一個索引,用於告訴函數從目標字符串的哪一個位置開始搜索。主要用於搜索目標字符串中全部匹配的子字符串,且每次搜索都從上一次找到的位置開始。如:安全

local t = {}
local i = 0
while true do
    i = string.find(s,"\n",i+1)
    if i == nil then
        break
    end
    t[#t + 1] = i
end

  2). string.match函數:
    該函數返回目標字符串中和模式字符串匹配的部分。如:函數

1 date = "Today is 2012-01-01"
2 d = string.match(date,"%d+\-%d+\-%d+")
3 print(d)  --輸出2012-01-01

    3). string.gsub函數:
    該函數有3個參數,目標字符串、模式和替換字符串。基本用法是將目標字符串中全部出現模式的地方替換爲替換字符串。如:
    print(string.gsub("Lua is cute","cute","great"))  --輸出Lua is great
    post

  該函數還有可選的第4個參數,即實際替換的次數。
    print(string.gsub("all lii","l","x",1))  --輸出axl lii
    print(string.gsub("all lii","l","x",2))  --輸出axx lii測試


    函數string.gsub 返回還有另外一個結果,即實際替換的次數。
    count = select(2, string.gsub(str," "," "))  --輸出str中空格的數量lua

  還能根據這個函數來實現一些其餘的功能,譬如 split string:url

string.split = function(s, p)
    local rt= {}
    string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
    return rt
end

-- 測試代碼以下:
local str = "abc,123,hello,ok"
local list = string.split(str, ',')
for _, s in ipairs(list) do
    print(tostring(s))
end
-- 輸出結果以下 :
abc
123
hello
ok

    另外觀看 雲風的這篇文章,發現string.gsub函數 還能夠這樣用:spa

local str = "#qwe&qwe&qwe&##qwe&qwe&qwe&##qwe&qwe&qwe&##qwe&qwe&qwe&#"
str = str.rep(str , 1000)

str = string.gsub(str , '&', '&')
str = string.gsub(str , '#', '@@@')
str = string.gsub(str , 'q', 'Q')
str = string.gsub(str , '#', 'B-B')
print(str)

    上述的實現也可寫成這樣 來寫~以下:excel

local escapeAttrib = {
    ['&'] = '&';
    ['#'] = '@@@';
    ['q'] = 'Q';
    ['e'] = 'B-B';
}

local str = "#qwe&qwe&qwe&##qwe&qwe&qwe&##qwe&qwe&qwe&##qwe&qwe&qwe&#"
str = str.rep(str , 1000)
str = string.gsub(str , '[&#qe]', escapeAttrib)
print(str)

  使用lua自帶的SciTe 跑了屢次,目測 前者表現會稍好一點;code

  4). string.gmatch函數:
    返回一個函數,經過這個返回的函數能夠遍歷到一個字符串中全部出現指定模式的地方。如:

words = {}
s = "hello world"
for w in string.gmatch(s,"%a+") do                                                                                                                                            print("----")
    print(w)
    words[#words + 1] = w
end
--輸出結果爲: 
----
hello                                                                                                ----world

    3. 模式:
    下面的列表給出了Lua目前支持的模式元字符;

模式元字符 描述
. 全部字符
%a 字母
%c 控制字符
%d 數字
%l 小寫字母
%p 標點符號
%s 空白字符
%u 大寫字母
%w 字母和數字字符
%x 十六進制數字
%z 內部表示爲0的字符

    這些元字符的大寫形式表示它們的補集,如%A,表示全部非字母字符。
    print(string.gsub("hello, up-down!","%S","."))   --輸出hello..up.down. 4
    上例中的4表示替換的次數。
    除了上述元字符以外,Lua還提供了另外幾個關鍵字符。如:( ) . % + - * ? [ ] ^ $
    其中%表示轉義字符,如%.表示點(.),%%表示百分號(%)
    方括號[]表示將不一樣的字符分類,便可建立出屬於本身的字符分類,如[%w_]表示匹配字符、數字和下劃線。
    橫線(-)表示鏈接一個範圍,好比[0-9A-Z]
    若是^字符在方括號內 ,如[^\n],表示除\n以外的全部字符,即表示方括號中的分類的補集若是^不在方括號內,則表示之後面的字符開頭$和它正好相反,表示之前面的字符結束。如:^Hello%d$,匹配的字符串可能爲Hello一、Hello2等。
    在Lua中還提供了4種用來修飾模式中的重複部分,如:+(重複1次或屢次)、*(重複0次或屢次)、-(重複0次或屢次)和?(出現0或1次)。如:
    print(string.gsub("one, and two; and three","%a+","word")) --輸出word, word word; word word
    print(string.match("the number 1298 is even","%d+")) --輸出1298
    星號(*)和橫線(-)的主要差異是,星號老是試圖匹配更多的字符,而橫線則老是試圖匹配最少的字符。

格式字符串可能包含如下的轉義碼:

%c - 接受一個數字, 並將其轉化爲ASCII碼錶中對應的字符
%d, %i - 接受一個數字並將其轉化爲有符號的整數格式
%o - 接受一個數字並將其轉化爲八進制數格式
%u - 接受一個數字並將其轉化爲無符號整數格式
%x - 接受一個數字並將其轉化爲十六進制數格式, 使用小寫字母
%X - 接受一個數字並將其轉化爲十六進制數格式, 使用大寫字母
%e - 接受一個數字並將其轉化爲科學記數法格式, 使用小寫字母e
%E - 接受一個數字並將其轉化爲科學記數法格式, 使用大寫字母E
%f - 接受一個數字並將其轉化爲浮點數格式
%g(%G) - 接受一個數字並將其轉化爲%e(%E, 對應%G)及%f中較短的一種格式
%q - 接受一個字符串並將其轉化爲可安全被Lua編譯器讀入的格式(即將該string添加了"")
%s - 接受一個字符串並按照給定的參數格式化該字符串

爲進一步細化格式, 能夠在%號後添加參數. 參數將以以下的順序讀入:

(1) 符號: 一個+號表示其後的數字轉義符將讓正數顯示正號. 默認狀況下只有負數顯示符號.
(2) 佔位符: 一個0, 在後面指定了字串寬度時佔位用. 不填時的默認佔位符是空格.
(3) 對齊標識: 在指定了字串寬度時, 默認爲右對齊, 增長-號能夠改成左對齊.
(4) 寬度數值 
(5) 小數位數/字串裁切: 在寬度數值後增長的小數部分n, 若後接f(浮點數轉義符, 如%6.3f)則設定該浮點數的小數只保留n位, 若後接s(字符串轉義符, 如%5.3s)則設定該字符串只顯示前n位.

    4. 捕獲(capture):
    捕獲功能可根據一個模式從目標字符串中抽出匹配於該模式的內容。在指定捕獲是,應將模式中須要捕獲的部分寫到一對圓括號內。對於具備捕獲的模式,函數string.match會將全部捕獲到的值做爲單獨的結果返回。即它會將目標字符串切成多個捕獲到的部分。如:

pair = "name = Anna"
key,value = string.match(pair,"(%a+)%s*=%s*(%a+)")
print(key,value)  --輸出name anna

date = "Today is 2012-01-02"
y,m,d = string.match(date,"(%d+)\-(%d+)\-(%d+)")
print(y,m,d)      --輸出2012    01      02

 還能夠對模式自己使用捕獲。即%1表示第一個捕獲,以此類推,%0表示整個匹配,如:

1 print(string.gsub("hello Lua","(.)(.)","%2%1"))  --將相鄰的兩個字符對調,輸出爲ehll ouLa
2 print(string.gsub("hello Lua!","%a","%0-%0"))    --輸出爲h-he-el-ll-lo-o L-Lu-ua-a!

5. 替換:
    string.gsub函數的第三個參數不只能夠是字符串,也能夠是函數或table,若是是函數,string.gsub會在每次找到匹配時調用該函 數,調用時的參數就是捕獲到的內容,而該函數的返回值則做爲要替換的字符串。當用一個table來調用時,string.gsub會用每次捕獲到的內容做 爲key,在table中查找,並將對應的value做爲要替換的字符串。若是table中不包含這個key,那麼string.gsub不改變這個匹 配。如:

function expand(s)
    return (string.gsub(s,"$(%w+)",_G))
end

name = "Lua"; status = "great"
print(expand("$name is $status, isn't it?"))  --輸出 Lua is great, isn't it?
print(expand("$othername is $status, isn't it?"))  --輸出 $othername is great, isn't it?

function expand2(s)
    return (string.gsub(s,"$(%w+)",function(n) return tostring(_G[n]) end))
end

print(expand2("print = $print; a = $a")) --輸出 print = function: 002B77C0; a = nil

另外:附上網路上關於Lua的table和String相互轉化的方法以下:

-- 序列化tablle表--將表轉化成string
function serialize(obj)
    local lua = ""
    local t = type(obj)
    if t == "number" then
        lua = lua .. obj
    elseif t == "boolean" then
        lua = lua .. tostring(obj)
    elseif t == "string" then
        lua = lua .. string.format("%q", obj)
    elseif t == "table" then
        lua = lua .. "{\n"
    for k, v in pairs(obj) do
        lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
    end
    local metatable = getmetatable(obj)
        if metatable ~= nil and type(metatable.__index) == "table" then
        for k, v in pairs(metatable.__index) do
            lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
        end
    end
        lua = lua .. "}"
    elseif t == "nil" then
        return nil
    else
        return "-nil-" 
        --error("can not serialize a " .. t .. " type.")
    end
    return lua
end

-- 反序列化tablle表--將string轉化成table
function unserialize(lua)
    local t = type(lua)
    if t == "nil" or lua == "" then
        return nil
    elseif t == "number" or t == "string" or t == "boolean" then
        lua = tostring(lua)
    else
        error("can not unserialize a " .. t .. " type.")
    end
    lua = "return " .. lua
    local func = loadstring(lua)
    if func == nil then
        return nil
    end
    return func()
end

未完帶整理;閱參考文章 請Click :Here

相關文章
相關標籤/搜索