婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁(yè) > 知識(shí)庫(kù) > OpenResty中正則模式匹配的2種方法詳解

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

熱門(mén)標(biāo)簽:昆明電話(huà)外呼系統(tǒng)好么 陜西便宜電銷(xiāo)機(jī)器人軟件 電話(huà)機(jī)器人每天搜索多少次 杞縣地圖標(biāo)注app 衡水外呼線(xiàn)路解決 海口智能語(yǔ)音電銷(xiāo)機(jī)器人好用嗎 艾比利外呼系統(tǒng) 免費(fèi)門(mén)店地圖標(biāo)注注冊(cè)入駐 外呼系統(tǒng)一天耗費(fèi)多少流量

前言

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

首先需要說(shuō)明的是,OpenResty 套件中包含了兩種語(yǔ)法:一種是主要基于 FFI API 實(shí)現(xiàn)的 OpenResty 語(yǔ)法,一種是類(lèi)原生 Lua 腳本語(yǔ)言的語(yǔ)法。

在本文所介紹的內(nèi)容中,對(duì)應(yīng)以上兩種語(yǔ)法的正則模式匹配分別是 ngx.re.find 和 string.find 。

這兩種規(guī)則起到完全相同的作用:在 subject string 中搜索指定的模式的串,若找到匹配值就返回它的開(kāi)始位置和結(jié)束位置的位數(shù),否則返回兩個(gè) nil 空值。需要注意的是,當(dāng)查找到模式時(shí)才會(huì)產(chǎn)生兩個(gè)值,當(dāng)例如只有一個(gè)變量時(shí)只會(huì)產(chǎn)生開(kāi)始位置位數(shù)或一個(gè) nil 空值。

即使你對(duì) Lua 比較熟悉,也已不再建議使用 string.find 等 Lua 的正則語(yǔ)法。一是因?yàn)橛捎趯?shí)現(xiàn)不同,Lua 提供的正則表達(dá)式的性能相比 ngx.re.* 的表現(xiàn)要遜色不少,二是 Lua 的正則語(yǔ)法并不符合 POSIX 規(guī)范,而 ngx.re.* 則由標(biāo)準(zhǔn) POSIX 規(guī)范進(jìn)行實(shí)現(xiàn),后者明顯更具備通用性和現(xiàn)在意義。

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

string.find

雖說(shuō)已經(jīng)實(shí)在沒(méi)什么要用 string.find 的必要(前浪死在沙灘上),不過(guò)我還是打算簡(jiǎn)單介紹下,因?yàn)槲椰F(xiàn)在就是用的這個(gè)(原因我在后文會(huì)提到)。

-- syntax
from, to, err = string.find(s, pattern, start, [plain])

-- context
init_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*

-- example
string.find(ngx.var.http_user_agent, "360")

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

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

-- 輸出
ngx.say("var=" .. var)

把它放到 Nginx 網(wǎng)站的 /example 路徑下:

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

然后使用 curl 測(cè)試響應(yīng):

# 發(fā)個(gè)請(qǐng)求,順便指定 UA 為 360
curl example.com -A "360"

# 返回響應(yīng)會(huì)看到由 ngx.say echo 回來(lái)的字符串
# 這里匹配到的 "360" 字符串位于字首,位數(shù)是 1
var=1

ngx.re.find

ngx.re.find 規(guī)范的優(yōu)勢(shì)已經(jīng)在上文介紹過(guò)了,這里介紹下它的基本語(yǔ)法(更多說(shuō)明可以參看 官方文檔 ),以及要發(fā)揮它的優(yōu)勢(shì)(使用 “o” 參數(shù)緩存和使用 pcre JIT)的所需要求。

-- syntax
from, to, err = ngx.re.find(subject, regex, options?, ctx?, nth?)

-- context
init_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*

-- example
ngx.re.find(ngx.var.http_user_agent, "360", "jo")

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

同樣作為前面舉例的實(shí)現(xiàn),Lua 代碼變成了這樣:

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

-- 輸出
ngx.say("var=" .. var)

我的坑

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

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

然后我就發(fā)現(xiàn),這個(gè)匹配坑我了,我把這段代碼單獨(dú)拿出來(lái)時(shí)訪(fǎng)問(wèn) /admin/xxx 或 /tools/xxx 就會(huì)被拒,但是我一把它放進(jìn)代碼構(gòu)筑后就形同虛設(shè)。當(dāng)然我能肯定不是我其它代碼的問(wèn)題,因?yàn)閾Q成 string.find 后就好了。

為了確認(rèn)是不是正則寫(xiě)錯(cuò)的鍋,我也做過(guò)以下測(cè)試:

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"))
 end
elseif (ngx.var.request_uri == "/test2/") then
 if (ngx.re.find("/admintest/", "^/admin/", "jo") ~= nil) then
  ngx.say("2=" .. ngx.re.find("/admintest/", "^/admin/", "jo"))
 end
elseif (ngx.var.request_uri == "/test3/") then
 if (ngx.re.find("/artic/", "^/admin/", "jo") ~= nil) then
  ngx.say("3=" .. ngx.re.find("/artic/", "^/admin/", "jo"))
 end
elseif (ngx.var.request_uri == "/test4/") then
 if (ngx.re.find("/artic", "^/admin/", "jo") ~= nil) then
  ngx.say("4=" .. ngx.re.find("/artic", "^/admin/", "jo"))
 end
elseif (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"))
 end
elseif (ngx.var.request_uri == "/test6/") then
 if (ngx.re.find("/offline/", "^/admin/", "jo") ~= nil) then
  ngx.say("6=" .. ngx.re.find("/offline/", "^/admin/", "jo"))
 end
elseif (ngx.var.request_uri == "/test7/") then
 if (ngx.re.find("/admin/", "^/admin/", "jo") ~= nil) then
  ngx.say("7=" .. ngx.re.find("/admin/", "^/admin/", "jo"))
 end
elseif (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"))
 end
else
 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
 end
end

測(cè)試結(jié)果卻表明我的寫(xiě)法并沒(méi)有錯(cuò),根據(jù) echo 的結(jié)果作出的判斷是, ^/admin/ 的確對(duì) /admin/xxx 進(jìn)行了唯一匹配。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

您可能感興趣的文章:
  • Openresty服務(wù)器使用lua腳本寫(xiě)的Hello World簡(jiǎn)單實(shí)例

標(biāo)簽:泰安 海口 南京 宿遷 昌都 臨滄 營(yíng)口 西寧

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《OpenResty中正則模式匹配的2種方法詳解》,本文關(guān)鍵詞  OpenResty,中,正則,模式,匹配,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《OpenResty中正則模式匹配的2種方法詳解》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于OpenResty中正則模式匹配的2種方法詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 镇安县| 雅安市| 漯河市| 张掖市| 玛沁县| 常州市| 阳城县| 梨树县| 崇州市| 上杭县| 喜德县| 汤阴县| 安溪县| 安陆市| 文昌市| 临朐县| 东明县| 开化县| 奉贤区| 新乡县| 辽源市| 梧州市| 呼图壁县| 吉林市| 惠水县| 楚雄市| 长葛市| 改则县| 巧家县| 利川市| 滕州市| 望江县| 吴桥县| 青河县| 延吉市| 广南县| 浏阳市| 阳泉市| 巴彦县| 甘泉县| 准格尔旗|