Lua 學習筆記(六) —— 字符串操做

1 模式

1.1 字符類

字符類表明一組字符。能夠用下列組合來表示一個字符類。html

組合 表明字母 表明字符類型
x (變量 x) ^$()%.[]*+-?之外的任一字符
. (dot) 任意字符
%a (alphabet) 字母
%b (bracket) 對稱字符以及字符間的內容
%c (control) 控制字符(即各種轉義符)
%d (digits) 數字
%l (lowercase) 小寫字母
%p (punctuation) 標點符號
%s (space) 空格
%u (uppercase) 大寫字母
%w (word) 字母和數字
%x (hexadecimal) 十六進制字符
%z (zero) 值爲 0 的字符,即 '\0'
%x (變量 x) 字母和數字之外的任一字符

若是組合中的字符寫成大寫形式(例如將 '%a' 寫成 '%A'),至關於對原來所表明的字符類型取補集git

例子:函數

前兩行的數字標出每一個字符的下標。find函數返回找出第一個符合查找條件的字符的下標。編碼

-----------------00000000001111111112 222222222333333333344444444445555 5
-----------------12345678901234567890 123456789012345678901234567890123 4
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","i")
    --> 6
x = string.find("Tutu is a young man.\n His student number is 20230001.\0",".")
    --> 1
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%a")    --> 1   
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%c")    --> 21 
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%d")    --> 45 
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%l")    --> 2   
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%p")    --> 20 
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%s")    --> 5   
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%u")    --> 1   
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%w")    --> 1   
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%x")    --> 9   
x = string.find("Tutu is a young man.\n His student number is 20230001.\0","%z")    --> 54

() 表示捕捉,find的第三個參數返回被捕捉到的字符串,在這裏即返回找到的那個字符。spa

x,y,z = string.find("%()~!@#$%^&*():\";\'?<>._[]","(%%)")   --> 1   1   %
x,y,z = string.find("%()~!@#$%^&*():\";\'?<>._[]","(%#)")   --> 7   7   #
x,y,z = string.find("%()~!@#$%^&*():\";\'?<>._[]","(%\")")  --> 16  16  "

下句中的 + 表示取一個或多個知足條件的連續字符。code

--1 2 3 4 5 6 7 8
x,y = string.find("\a\b\f\n\r\t\v\0","%c+")     --> 1   7

上句基本列出了全部控制字符,並非全部轉義符都是控制字符,例如 \\\xff 不屬於控制字符。orm

match 函數返回符合匹配條件的字符子串。htm

x = string.match("0123456789ABCDEFabcdefg","%x+")   --> 0123456789ABCDEFabcdef

輸出的符號即爲 %x 所支持的全部字符。blog

%b 的使用方法與前面的組合形式略有不一樣,其形式爲 %bxy,使用示例以下:ci

---------------------00000000001111111112 22222222233333333334444444444555555 5
---------------------12345678901234567890 12345678901234567890123456789012345 6
x,y,z = string.find("Tutu is a young man.\n His student number is [20230001].\0","(%b[])")  --> 45  54  [20230001]
x,y,z = string.find("Tutu is a young man.\n His student number is _20230001_.\0","(%b__)")  --> 45  54  _20230001_
x,y,z = string.find("Tutu is a young man.\n His student number is _20230001_.\0","(%b21)")  --> 48  53  230001

1.2 [] 字符集

字符集操做是對字符類組合的一個擴展。能夠經過 [] 制定出用戶所需的一套字符選取範圍。

---------------------0000000001111111111222222222
---------------------1234567890123456789012345678
x,y,z = string.find("[Email]: tangyikejun@163.com","([123])")           --> 22  22  1
x,y,z = string.find("[Email]: tangyikejun@163.com","([l]])")            --> 6   7   l]
x,y,z = string.find("[Email]: tangyikejun@163.com","([1-3])")           --> 22  22  1
x,y,z = string.find("[Email]: tangyikejun@163.com","([^1-3])")          --> 1   1   [
x,y,z = string.find("[Email]: tangyikejun@163.com","([^%d])")           --> 1   1   [
x,y,z = string.find("[Email]: tangyikejun@163.com","([0-9][%d][%d])")   --> 22  24  163
x,y,z = string.find("[Email]: tangyikejun@163.com","([0-9]+)")          --> 22  24  163

使用特色:

  1. 每一個字符集僅限定一個字符的範圍。
  2. 連字符 - 用於限定字符的範圍,值域根據字符在ASCII碼中對應的值得出,例如 [0-7] 表明字符範圍爲 0-7。
    x,y,z = string.find("!\"#$%&0123","([$-1]+)") --> 4 8 $%&01
  3. 添加 ^ 表示對指定的字符範圍取補集。[^%d] 等價於 [%D]

1.3 模式項

模式項 做用
+ 匹配1個或多個字符,儘量多地匹配
- 匹配0個或多個字符,儘量少地匹配
* 匹配0個或多個字符,儘量多地匹配
匹配0個或1個字符,儘量多地匹配

使用特色:

  1. 模式項都是針對前一個字符而言的。例如 abc- 做用於字符 c
---------------------0000000001
---------------------1234567890
x,y,z = string.find("aaaabbbccc","(%a+)")       --> 1   10  aaaabbbccc
x,y,z = string.find("bbbccc","(a+)")            --> nil nil nil
x,y,z = string.find("aaaabbbccc","(ab-c)")      --> 4   8   abbbc
-- x,y,z = string.find("aaaaccc","(ab-c)")      --> 4   5   ac
-- x,y,z = string.find("aaaaccc","(ab*c)")      --> 4   5   ac
-- x,y,z = string.find("aaaabccc","(ab?c)")     --> 4   6   abc
-- x,y,z = string.find("aaaabccc","(ba?c)")     --> 5   6   bc
---------------------000000000111 111111122
---------------------123456789012 345678901
x,y,z = string.find("tangyikejun\0 163.com","(%z%s%w+)")    --> 12  16  
x,y,z = string.find("tangyikejun\0163.com","(%z%d%w+)")     --> nil nil     nil

注意: \0 後面不能跟數字。並且用 find 返回的匹配字符串沒法輸出 \0 以後的部分。

1.4 模式

多個模式項組合造成模式

  • 模式的前面添加 ^ 表示匹配從目標字符串的起始位置開始。
  • 模式的末尾添加 $ 表示匹配目標字符串的末尾子串。
  • 其餘位置的 ^$ 做爲普通字符處理。
---------------------0000000001111111111222222222
---------------------1234567890123456789012345678
x,y,z = string.find("[Email]: tangyikejun@163.com","^(.%a+)")   -->1    6   [Email
x,y,z = string.find("[Email]: tangyikejun@163.com","(%a+)$")    -->26   28  com

1.5 ()捕捉

捕捉是指將括號內的組合匹配結果保存起來,每一個括號保存一個結果。
保存的數據的順序按照左括號的順序排列。

x,y,z,h,l = string.find("Tutu is a young man.\n His student number is _20230001_.\0","((%a+%s)(%a+%s)%b__)")    --> 35  54  number is _20230001_    number  is

字符串模式匹配可參考Lua模式匹配

2 庫函數

  • 字符串的下標從1開始。正數下標表示正向下標,負數表示反向下標(例如 -1 表示字符串最後一個字符)。
  • 函數均默認支持模式匹配。
  • 返回的匹配字符串沒法輸出 \0 以後的部分。

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

查找字符串的子串,若是找到,返回子串的起始位置、結束位置;找不到返回 nil。
若是使用捕獲(即對模式串用括號包裹起來),則一併返回匹配獲得的字符串。

定義

string.find([字符串],[待查找字符串],[查找起始位置]=1,[禁用模式匹配]=false)

只有顯式指定了 init 參數才能控制 plain 參數。

例子

x,y,z = string.find("1001 is a Robot", "Robot")
print(x,y,z)                                --> 11 15   nil
x,y,z = string.find("1001 is a Robot","1%d",1,true)
print(x,y,z)                                --> nil nil nil
x,y,z = string.find("1001 is a Robot","(%d+)",1,false)
print(x,y,z)                                --> 1   2   1001

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

string.find 相似,返回值不同。string.match 查找字符串的子串,若是找到,返回子串;找不到返回 nil。

支持模式匹配。

定義

例子

x = string.match("1001 is a Robot","001")
print(x)                --> 001                             
x = string.match("1001 is a Robot","%d%d")
print(x)                --> 10

string.gmatch(s,pattern)

返回一個迭代函數,該函數每執行一次,就返回下一個捕捉到的匹配(若是沒有使用捕捉,就返回整個匹配結果)。

例子

for s in string.gmatch("I have a Dream.","%a+") do
    print(s)
end
--> I
--> have
--> a
--> Dream
t = {}
s = "name=tangyikejun, number=20250001"

-- 將捕獲的兩個子串分別做爲鍵和值放到表t中
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
    t[k] = v
end

-- 輸出表t
for k,v in pairs(t) do
    print(k,v)
end

--> name    tangyikejun
--> number  20250001

string.format(formatstring,...)

返回格式化以後的字符串。

定義

例子

string.format("My name is %s", "tangyikejun")   --> My name is tangyikejun

string.len(s)

返回字符串長度

string.lower(s)

返回小寫字母的字符串

string.upper(s)

返回大寫字母的字符串

string.rep(s,n)

對字符串進行重複

定義

string.rep([字符串],[重複次數])

例子

string.rep("Hello",4)   -- HelloHelloHelloHello

string.reverse(s)

返回反轉後的字符串。

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

返回子字符串。

定義

string.sub([字符串],[開始字符下標],[結束字符下標]=-1)

例子

x = string.sub("tangyikejun",7)
print(x)                --> kejun
x = string.sub("tangyikejun",1,-6)
print(x)                --> tangyi

string.gsub(s,pattern,repl[,n])

根據模式匹配對字符串中每個匹配部分都作替換處理,返回替換後的字符串。

定義

string.gsub([字符串],[模式匹配],[替換字符],[最大替換次數] = 無限制)

repl 參數([替換字符])支持 字符串、表、函數。

若是 repl 是字符串,那麼該字符串就是用於替換的字符串。同時支持 %n 轉義符操做,n 的範圍是 0-9。n 範圍爲 [1,9] 時表示第 n 個捕獲的匹配字符串,%0 表示整個匹配的字符串,%% 表示替換爲一個 %

若是 repl 是表,那麼將捕獲的第一個字符串做爲鍵值(Key)進行查詢(沒有定義捕捉則以整個匹配的字符串爲鍵值),查到的值做爲替換的字符串。

若是 repl 是函數,那麼每次匹配成功都會調用該函數,並以按序以全部捕捉做爲參數傳入函數。沒有捕捉則以整個匹配的字符做爲參數。

若是從表或函數獲得是字符串或者是數字,就將其用於替換;若是獲得的是 false 或 nil,那麼匹配部分將不會發生變化。

例子

repl 爲字符串

s = "Never say die."
x = string.gsub(s,"die","never")            --> Never say never.
x = string.gsub(s,"die","'%0'")             --> Never say 'die'.
x = string.gsub(s,"(%a+)%s%a+%s(%a+)","%2") --> die.

限制最大替換次數

s = "never say never."
x = string.gsub(s,"never","Never",1)    --> Never say never.

repl 是表

t = {name="Lua",version="5.1"}
x = string.gsub("$name-$version.tar.gz","$(%a+)",t) --> Lua-5.1.tar.gz

repl是函數

x = string.gsub("4+5 = $return 4+5$","%$(.-)%$",function(s)return loadstring(s)() end)  --> 4+5 = 9
x = string.gsub("23+45=$result", "((%d+)%+(%d+)=)%$%a+", function (s,a,b)
    sum = a+b
    return s..sum
end)    --> 23+45=68

~~注意:彷佛只支持匿名函數。~~

從表或函數返回的是 false 或 nil

x = string.gsub("4+5 = $return 4+5$","%$(.-)%$",function(s)return nil end)  --> 4+5 = $return 4+5$
t = {name="Lua",version=false}
x = string.gsub("$name-$version.tar.gz","$(%a+)",t) --> Lua-$version.tar.gz

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

返回字符的 ASCII 碼值。

定義

string.byte([字符串],[起始下標]=1,[結束下標]=[起始下標])

例子

x,y,z = string.byte("abc",2)    --> 98  nil nil
x,y,z = string.byte("abc",1,3)  --> 97  98  99

string.char(...)

根據傳入的 ASCII 編碼值([0-255])獲得對應的字符,傳入多少編碼值就返回多長的字符串。

例子

x = string.char(98,99,100)  --> bcd

若是輸入字符超限會編譯報錯。

string.dump(function)

返回函數的二進制表示(字符串形式),把這個返回值傳給 loadingstring 能夠得到函數的一份拷貝(傳入的函數必須是沒有上值的 Lua 函數)。

例子

function sum(a,b)
    return a + b
end

s = string.dump(sum)
x = loadstring(s)(4,4) -- 8

參考連接

Lua模式匹配(參考了此文中對 %b 的使用)

相關文章
相關標籤/搜索