亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

OpenResty中正則模式匹配的2種方法詳解

2024-07-21 23:05:03
字體:
來源:轉載
供稿:網友

前言

本文介紹 OpenResty 的兩種正則模式匹配。

首先需要說明的是,OpenResty 套件中包含了兩種語法:一種是主要基于 FFI API 實現的 OpenResty 語法,一種是類原生 Lua 腳本語言的語法。

在本文所介紹的內容中,對應以上兩種語法的正則模式匹配分別是 ngx.re.find 和 string.find 。

這兩種規則起到完全相同的作用:在 subject string 中搜索指定的模式的串,若找到匹配值就返回它的開始位置和結束位置的位數,否則返回兩個 nil 空值。需要注意的是,當查找到模式時才會產生兩個值,當例如只有一個變量時只會產生開始位置位數或一個 nil 空值。

即使你對 Lua 比較熟悉,也已不再建議使用 string.find 等 Lua 的正則語法。一是因為由于實現不同,Lua 提供的正則表達式的性能相比 ngx.re.* 的表現要遜色不少,二是 Lua 的正則語法并不符合 POSIX 規范,而 ngx.re.* 則由標準 POSIX 規范進行實現,后者明顯更具備通用性和現在意義。

還有一個很重要的原因,相比 string.* 的每次都需重新編譯一遍,OpenResty 提供的 ngx.re.* 規范能夠在編譯完成后對 Pattern 進行緩存(使用 “o” 參數),并且也能通過 “j” 參數啟用 JIT 來進一步提升性能(需 pcre JIT 支持)。

string.find

雖說已經實在沒什么要用 string.find 的必要(前浪死在沙灘上),不過我還是打算簡單介紹下,因為我現在就是用的這個(原因我在后文會提到)。

-- syntaxfrom, to, err = string.find(s, pattern, start, [plain])-- contextinit_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer./*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*-- examplestring.find(ngx.var.http_user_agent, "360")

以上示例的作用就是包含有 “360” 的 UA 進行匹配,匹配命中時返回的值為 匹配串的開始位置和結束位置的位數(從左往右) 。舉個例子,使用 ngx.say 對輸出值進行顯示,先完成以下代碼:

-- 定義變量var = string.find(ngx.var.http_user_agent, "360")-- 輸出ngx.say("var=" .. var)

把它放到 Nginx 網站的 /example 路徑下:

location = /example { access_by_lua_block { var = string.find(ngx.var.http_user_agent, "360") ngx.say("var=" .. var) }}

然后使用 curl 測試響應:

# 發個請求,順便指定 UA 為 360curl example.com -A "360"# 返回響應會看到由 ngx.say echo 回來的字符串# 這里匹配到的 "360" 字符串位于字首,位數是 1var=1

ngx.re.find

ngx.re.find 規范的優勢已經在上文介紹過了,這里介紹下它的基本語法(更多說明可以參看 官方文檔 ),以及要發揮它的優勢(使用 “o” 參數緩存和使用 pcre JIT)的所需要求。

-- syntaxfrom, to, err = ngx.re.find(subject, regex, options?, ctx?, nth?)-- contextinit_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer./*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*-- examplengx.re.find(ngx.var.http_user_agent, "360", "jo")

要使用 ngx.re.* 規范,并且要實現更高性能的話,需要滿足三個條件:編譯時使用 –with-pcre-jit 參數以啟用 pcre JIT 支持;編譯時需要 lua-resty-core 支持(直接使用 OpenResty 安裝即可);以及使用 Lua 代碼時,需要在 init_by_lua 段引入 require 'resty.core.regex' 語句(引入 lua-resty-core API 支持),并在構建代碼時將使用 "jo" 參數作為你的習慣,這兩個參數提供 pcre JIT 和 Pattern Cache 開關。正如上面 example 中所用的那樣。

同樣作為前面舉例的實現,Lua 代碼變成了這樣:

-- 定義變量var = ngx.re.find(ngx.var.http_user_agent, "360", "jo")-- 輸出ngx.say("var=" .. var)

我的坑

最后來解釋下我為什么還在用 string.find 語法。原因比較尷尬,不是我不想用,而是我不能用。我使用了以下代碼:

if (ngx.re.find(ngx.var.request_uri, "^/admin/", "jo") ~= nil or ngx.re.find(ngx.var.request_uri, "^/tools/", "jo") ~= nil) then return ngx.exit(ngx.HTTP_CLOSE)end

然后我就發現,這個匹配坑我了,我把這段代碼單獨拿出來時訪問 /admin/xxx 或 /tools/xxx 就會被拒,但是我一把它放進代碼構筑后就形同虛設。當然我能肯定不是我其它代碼的問題,因為換成 string.find 后就好了。

為了確認是不是正則寫錯的鍋,我也做過以下測試:

if (ngx.var.request_uri == "/test1/") then if (ngx.re.find("/admin/test/", "^/admin/", "jo") ~= nil) then  ngx.say("1=" .. ngx.re.find("/admin/test/", "^/admin/", "jo")) endelseif (ngx.var.request_uri == "/test2/") then if (ngx.re.find("/admintest/", "^/admin/", "jo") ~= nil) then  ngx.say("2=" .. ngx.re.find("/admintest/", "^/admin/", "jo")) endelseif (ngx.var.request_uri == "/test3/") then if (ngx.re.find("/artic/", "^/admin/", "jo") ~= nil) then  ngx.say("3=" .. ngx.re.find("/artic/", "^/admin/", "jo")) endelseif (ngx.var.request_uri == "/test4/") then if (ngx.re.find("/artic", "^/admin/", "jo") ~= nil) then  ngx.say("4=" .. ngx.re.find("/artic", "^/admin/", "jo")) endelseif (ngx.var.request_uri == "/test5/") then if (ngx.re.find("/offline/admin/", "^/admin/", "jo") ~= nil) then  ngx.say("5=" .. ngx.re.find("/offline/admin/", "^/admin/", "jo")) endelseif (ngx.var.request_uri == "/test6/") then if (ngx.re.find("/offline/", "^/admin/", "jo") ~= nil) then  ngx.say("6=" .. ngx.re.find("/offline/", "^/admin/", "jo")) endelseif (ngx.var.request_uri == "/test7/") then if (ngx.re.find("/admin/", "^/admin/", "jo") ~= nil) then  ngx.say("7=" .. ngx.re.find("/admin/", "^/admin/", "jo")) endelseif (ngx.var.request_uri == "/test8/") then if (ngx.re.find("/adm/in", "^/admin/", "jo") ~= nil) then  ngx.say("8=" .. ngx.re.find("/adm/in", "^/admin/", "jo")) endelse if (ngx.var.request_uri == "/test9/") then  if (ngx.re.find("/admin", "^/admin/", "jo") ~= nil) then   ngx.say("9=" .. ngx.re.find("/admin", "^/admin/", "jo"))  end endend

測試結果卻表明我的寫法并沒有錯,根據 echo 的結果作出的判斷是, ^/admin/ 的確對 /admin/xxx 進行了唯一匹配。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到lua頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲激情视频在线观看| 久久久久久久成人| 97视频网站入口| 日韩黄在线观看| 亚洲aaa激情| 一区二区三区回区在观看免费视频| 国产欧美欧洲在线观看| 国内成人精品一区| 97香蕉久久超级碰碰高清版| 一区二区在线视频播放| 国产精品入口日韩视频大尺度| 欧美国产日本高清在线| 久久久亚洲国产天美传媒修理工| 亚洲人成网站777色婷婷| 亚洲性线免费观看视频成熟| 亚洲另类激情图| 国产丝袜精品视频| 国产女精品视频网站免费| 这里只有精品在线播放| 国产亚洲一区精品| 国产人妖伪娘一区91| 中文字幕精品久久| 国产综合香蕉五月婷在线| 国产精品视频区| 国产精品成人播放| 国产亚洲精品久久久久久777| 欧美日韩不卡合集视频| 一区二区三区www| 精品视频在线观看日韩| 人体精品一二三区| 色婷婷综合成人av| 一本色道久久88综合亚洲精品ⅰ| 国语自产在线不卡| 亚洲电影免费观看高清完整版在线观看| 中文字幕一精品亚洲无线一区| 精品国产区一区二区三区在线观看| 亚洲激情在线视频| 欧美日韩第一页| 欧美日韩国产在线播放| 久久露脸国产精品| 欧美在线视频a| 8090理伦午夜在线电影| 欧美老女人在线视频| 91夜夜揉人人捏人人添红杏| 日韩亚洲欧美中文在线| 日产精品久久久一区二区福利| 性色av一区二区三区红粉影视| 亚洲系列中文字幕| 亚洲美女精品久久| 国产精品中文字幕在线观看| 国产精品羞羞答答| 日韩美女av在线| 日韩av最新在线| 亚洲另类欧美自拍| 国产精品一区二区电影| 精品激情国产视频| 亚洲人在线视频| 久久久国产成人精品| 亚洲国产成人在线播放| 国产女同一区二区| 国产午夜精品麻豆| 欧美国产欧美亚洲国产日韩mv天天看完整| 在线精品播放av| 成人欧美一区二区三区黑人孕妇| 亚洲欧美精品中文字幕在线| 久久久久99精品久久久久| 欧美日韩国内自拍| 亚洲视频在线播放| 精品亚洲一区二区| 在线不卡国产精品| 欧美福利视频网站| 久久久久久一区二区三区| 91久久久久久国产精品| 日韩av中文字幕在线播放| 欧美激情啊啊啊| 欧美大全免费观看电视剧大泉洋| 免费av在线一区| 韩国三级电影久久久久久| 日本成熟性欧美| 欧美在线免费观看| 日韩在线欧美在线| 欧美在线性爱视频| 亚洲情综合五月天| 日韩av在线导航| 欧美日本高清一区| 国产精品极品在线| 在线国产精品视频| 在线观看成人黄色| 亚洲色图校园春色| 亚洲无线码在线一区观看| 国产suv精品一区二区三区88区| 国产日韩欧美成人| 久久久久久国产精品美女| 久久久999成人| 日本中文字幕久久看| 国产91精品不卡视频| 欧美丰满少妇xxxxx做受| 欧美夫妻性生活xx| 日韩大胆人体377p| 亚洲国产一区二区三区在线观看| 亚洲色图13p| 92裸体在线视频网站| 欧美性20hd另类| 欧美国产日本高清在线| 欧美中文在线视频| 亚洲一级黄色av| 国产在线a不卡| 精品国产91乱高清在线观看| 国产高清视频一区三区| 一区二区亚洲精品国产| 国产免费一区二区三区在线观看| 国产精品白丝jk喷水视频一区| 久久影院免费观看| 91在线播放国产| 日韩黄色高清视频| 日韩欧美在线第一页| 日韩最新av在线| 久久av红桃一区二区小说| 亚洲精品视频二区| 久久久亚洲国产天美传媒修理工| 中文字幕亚洲无线码在线一区| 欧美人与物videos| 91欧美精品午夜性色福利在线| 69久久夜色精品国产69乱青草| 亚洲欧美综合区自拍另类| 韩日欧美一区二区| 日韩在线资源网| 97在线视频免费观看| 国产网站欧美日韩免费精品在线观看| 亚洲福利视频久久| 国产精品吴梦梦| 色一情一乱一区二区| 美女精品久久久| 亚洲欧美日韩直播| 亚洲视频在线免费看| 欧美高清在线视频观看不卡| 久久久久国产精品免费网站| 亚洲国产97在线精品一区| 精品福利在线视频| 97视频在线观看播放| 欧美孕妇毛茸茸xxxx| 美女扒开尿口让男人操亚洲视频网站| 欧美疯狂性受xxxxx另类| 欧美福利视频在线观看| 姬川优奈aav一区二区| 亚洲精品视频中文字幕| 亚洲最大福利视频网站| 久久久久亚洲精品| 成人乱色短篇合集| 国产精品丝袜久久久久久不卡| 91视频九色网站| 日韩大片免费观看视频播放| 性色av一区二区三区在线观看| 国产综合久久久久| 亚洲tv在线观看| 91中文在线观看| 美女撒尿一区二区三区| 1769国内精品视频在线播放| 国产精品久久久久久久久影视| 成人亲热视频网站| 国产日韩在线播放| 久久精品视频免费播放| 一本大道香蕉久在线播放29| 亚洲一区二区久久久久久|