国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Lua 字符串查找函數(shù) string.find

原創(chuàng) 2017-01-11 13:44:46 1013
摘要:函數(shù)原型 string.find(s, pattern [, init [, plain]] ) s: 源字符串 pattern: 待搜索模式串 init: 可選, 起始位置 plain: 我沒用過  ① 子串匹配: [plain] view plain copyprint(string.find(

函數(shù)原型 string.find(s, pattern [, init [, plain]] )
 s: 源字符串
 pattern: 待搜索模式串
 init: 可選, 起始位置
 plain: 我沒用過
 
 ① 子串匹配:
 

[plain] view plain copy

print(string.find("haha", 'ah') )  ----- 輸出 2 3  


 注意: lua 里面數(shù)組或者字符串的字符, 其下標(biāo)索引是從 1 開始, 不是 0
  string.find 默認(rèn)情況下返回兩個(gè)值, 即查找到的子串的 起止下標(biāo), 如果不存在匹配返回 nil。
 如果我們只想要 string.find 返回的第二個(gè)值, 可以使用 虛變量(即 下劃線)
 

[plain] view plain copy

_, q=string.find("haha", 'ah')  

 print(q)  ----- 輸出 3  


 
 ② 模式匹配:
 

[plain] view plain copy

pair = " name = Anna "  

 print(string.find(pair, "(%a+)%s*=%s*(%a+)") ---- 輸出 2 12 name Anna  


 解釋:
 如果 find 的第二個(gè)參數(shù)使用了某種匹配模式, 并且模式串里面帶括號。 那么表示會(huì)“捕捉”括號括起來的模式匹配到的字符串。 捕捉, 當(dāng)然會(huì)把他們作為返回值。這里捕捉了兩下, 所以 find 多返回了兩個(gè)值
 
 那么, 這個(gè)模式是怎么匹配的呢?
 Lua 支持的字符類有:
 
 .  任意字符
 %s 空白符
 %p 標(biāo)點(diǎn)
 %c 控制字符
 %d 數(shù)字
 %x 十六進(jìn)制數(shù)
 %z 代表0的字符
 %a 字母
 %l 小寫字母
 %u 大寫字母
 %w 字母數(shù)字
字符類的大寫形式代表相應(yīng)集合的補(bǔ)集, 比如 %A 表示除了字母以外的字符集
另外,* + - 三個(gè),作為通配符分別表示:
*: 匹配前面指定的 0 或多個(gè)同類字符, 盡可能匹配更長的符合條件的字串
+: 匹配前面指定的 1 或多個(gè)同類字符, 盡可能匹配更長的符合條件的字串
-: 匹配前面指定的 0 或多個(gè)同類字符, 盡可能匹配更短的符合條件的字串

于是, "(%a+)%s*=%s*(%a+)" 表示, 先匹配一個(gè)或多個(gè)字母, 然后是零個(gè)或多個(gè)空白符(比如空格), 然后是個(gè) '=', 然后空白符, 然后字母。這樣, 滿足匹配的只有 "name = Anna"。 所以輸出位置為 2 12.
因?yàn)椴东@了兩個(gè) (%a+), 也就是 name, Anna 這兩個(gè)單詞, 所以還輸出了這兩個(gè)單詞

另外, lua 使用 %1-%9 表示拷貝捕獲。舉例說:

[plain] view plain copy

s="abc \"it's a cat\""  

_,_,_,q=string.find(s, "([\"'])(.-)%1")  

print(q)  -----輸出: it's a cat  


首先, [\"'] 表示匹配 雙引號或者單引號, 因?yàn)橛欣ㄌ枺砸柋徊东@。 然后匹配幾個(gè)任意字符并且捕獲他, 最后 %1 匹配與第一次捕獲到的(即引號)相同的字串。所以整個(gè)模式匹配到的是 "it's a cat", 而第二次捕獲的是去掉兩頭引號的字串, 即 it's a cat.

還有, '-' 與 '*' 到底有什么不同呢? 在上面, "([\"'])(.*)%1" 匹配到的結(jié)果與 '-' 是一樣的。盡可能匹配更長, 盡可能匹配更短 究竟什么不同呢?看例子:

[plain] view plain copy

print( ("\"hello\" \"hello\""):find('"(.+)"') )  ----輸出 1 15 hello" "hello  

print( ("\"hello\" \"hello\""):find('"(.-)"') )  ----輸出 1 7 hello  


* 盡可能長, 所以匹配了首尾兩個(gè) 引號, 捕獲了中間的 (hello" "hello)
- 盡可能短, 所以碰到第二個(gè)引號就說匹配完了, 因此只捕獲了第一個(gè) (hello)


發(fā)佈手記

熱門詞條