正則表達(dá)式又稱規(guī)則表達(dá)式(Regular Expression,在代碼中常簡(jiǎn)寫為 regex、regexp 或 RE),是一種用于匹配、查找、替換文本的強(qiáng)大工具。它能夠以特定的模式匹配字符串,從而實(shí)現(xiàn)自動(dòng)化文本處理。在許多編程語(yǔ)言中,正則表達(dá)式都被廣泛用于文本處理、數(shù)據(jù)分析、網(wǎng)頁(yè)抓取等領(lǐng)域。通過(guò)正則表達(dá)式,我們可以精確地篩選、操作和格式化文本,提高工作效率。
正則表達(dá)式在日常生活中有著廣泛的應(yīng)用。比如,在處理電話號(hào)碼時(shí),我們可以使用正則表達(dá)式來(lái)驗(yàn)證號(hào)碼的格式是否正確。中國(guó)的電話號(hào)碼通常由11位數(shù)字組成,第一位為1,第二位通常為3-9,我們可以使用以下正則表達(dá)式來(lái)匹配這些號(hào)碼:
/^1[3-9]d{9}$/
通過(guò)這個(gè)正則表達(dá)式,我們可以判斷一個(gè)電話號(hào)碼是否符合規(guī)范,從而避免出現(xiàn)錯(cuò)誤的信息輸入。
什么是正則表達(dá)式
每個(gè)正則表達(dá)式都有一個(gè)有限自動(dòng)機(jī)(也稱為狀態(tài)機(jī)),它接受表達(dá)式指定的語(yǔ)言,并使用 Thompson 構(gòu)造算法將正則表達(dá)式轉(zhuǎn)化為一個(gè)與之等價(jià)的非確定有限狀態(tài)自動(dòng)機(jī)(NFA)。同時(shí),對(duì)于每個(gè)有限自動(dòng)機(jī)來(lái)說(shuō),還有一個(gè)描述該自動(dòng)機(jī)所接受語(yǔ)言的正則表達(dá)式。該表達(dá)式可以通過(guò)克萊恩算法或高斯消元法生成。
正則表達(dá)式的一個(gè)著名應(yīng)用是文本編輯器中的搜索和替換功能,計(jì)算機(jī)先驅(qū) Ken Thompson( UNIX 操作系統(tǒng)的開發(fā)者之一)首先在 20 世紀(jì) 60 年代的面向行編輯器 QED 中實(shí)現(xiàn)了該功能。此函數(shù)允許查找文本中的特定字符串,并根據(jù)需要將其替換為任何其他字符串。
正則表達(dá)式如何工作
正則表達(dá)式可以僅使用正則字符(例如 abc ),也可以使用正則字符和元字符的組合(例如 ab*c)。元字符的任務(wù)是描述某些字符的結(jié)構(gòu)或排列,例如字符是否應(yīng)位于行的開頭,或者字符是否只出現(xiàn)一次或多次出現(xiàn)。上面提到的正則表達(dá)式示例的工作原理如下:
abc:簡(jiǎn)單的正則表達(dá)式模式 abc 需要完全匹配。換句話說(shuō),該表達(dá)式以精確的順序搜索包含字符 “abc” 的所有字符串。例如可以匹配到:“a abc d” 及 “abc oulomb”。
ab*c:相比之下,具有特殊字符的正則表達(dá)式略有不同。星號(hào)代表表達(dá)式搜索以字母 “a” 開頭并以字母 “c” 結(jié)尾的字符串。但是,a 和 c 之間可以有任意數(shù)量的 b。所以,“abc” 以及字符串 “abbbbc” 和 “cbb abbc ba” 也構(gòu)成了匹配。
每個(gè)正則表達(dá)式還可以鏈接到特定的操作,例如上面提到的 “替換” 操作。只要正則表達(dá)式為真,即只要存在上面示例中所述的匹配項(xiàng),就會(huì)執(zhí)行此操作。又拍云 CDN 的邊緣規(guī)則中就支持類似場(chǎng)景,根據(jù)正則表達(dá)式匹配字符串,執(zhí)行改寫、跳轉(zhuǎn)、訪問(wèn)控制、限速等需求。
使用正則表達(dá)式的挑戰(zhàn)
掌握正則表達(dá)式可以提高我們編程和文本處理的能力,更加高效地處理大量數(shù)據(jù)和文本。然而,掌握和使用還是存在著一些挑戰(zhàn)。
復(fù)雜性:正則表達(dá)式本身較為復(fù)雜,學(xué)習(xí)曲線陡峭,編寫和理解復(fù)雜的正則表達(dá)式可能需要大量的時(shí)間和經(jīng)驗(yàn)。
匹配效率:不合理的正則表達(dá)式可能導(dǎo)致效率低下,特別是在處理大量數(shù)據(jù)時(shí)。
不可讀性:復(fù)雜的正則表達(dá)式可能難以理解,使得維護(hù)和調(diào)試變得困難。
學(xué)習(xí)成本:正則表達(dá)式的語(yǔ)法和特殊字符較多,需要一定的學(xué)習(xí)才能熟練使用。
編寫正則表達(dá)式時(shí),最重要的是掌握以下幾個(gè)核心概念:
元字符:包括字符、反斜杠、方括號(hào)、星號(hào)、問(wèn)號(hào)等,它們用于匹配特定的字符或字符集。
轉(zhuǎn)義字符:使用反斜杠對(duì)特殊字符進(jìn)行轉(zhuǎn)義,以便匹配這些字符本身而不是其特殊含義。
限定符:用于指定正則表達(dá)式中前一個(gè)字符或子表達(dá)式出現(xiàn)的次數(shù)。例如,* 表示零次或多次,+ 表示一次或多次,? 表示零次或一次。
選擇符:使用管道符號(hào)(|)表示可以選擇多個(gè)模式中的任何一個(gè)進(jìn)行匹配。
原子:用于指定一個(gè)精確的字符或字符集,例如 d 表示數(shù)字字符,w 表示字母、數(shù)字或下劃線字符。
斷言:用于指定一個(gè)位置而不是具體的字符或字符集,例如 ^ 表示行首,$ 表示行尾。
括號(hào):用于將多個(gè)模式組合成一個(gè)更復(fù)雜的模式,并指定匹配的順序。
掌握了這些核心概念,就能夠編寫更準(zhǔn)確、更復(fù)雜的正則表達(dá)式,以解決各種文本處理問(wèn)題。
哪些語(yǔ)法規(guī)則適用正則表達(dá)式
正則表達(dá)式可以在多種語(yǔ)言中使用,例如 Perl、Python、Ruby、JavaScript、XML 或 HTML,但它們的用途或功能可能有很大不同。如在 JavaScript 中,正則表達(dá)式模式用于 search()、match() 或 replace() 字符串方法,而 XML 文檔中的表達(dá)式用于分隔元素內(nèi)容。不過(guò)就語(yǔ)法而言,在編程語(yǔ)言或標(biāo)記語(yǔ)言中使用幾乎沒(méi)有任何區(qū)別。
正則表達(dá)式可以由三個(gè)部分組成,無(wú)論使用哪種語(yǔ)言:
Patterns(表達(dá)式) | 由元字符、普通字符和特殊字符組成,用于描述要匹配的文本模式。該模式可以僅由簡(jiǎn)單字符組成,也可以由簡(jiǎn)單字符和特殊字符的組合組成。 |
Delimiters(分隔符) | 用于將正則表達(dá)式與其他文本區(qū)分開來(lái)。常用的分隔符是斜杠(/),但也可以使用其他字符作為分隔符。 |
Modifiers(修飾符) | 用于指定正則表達(dá)式的行為。常見的修飾符包括 i(忽略大小寫)、m(多行模式)、s(將點(diǎn)號(hào)匹配任何字符,包括換行符)和 x(忽略空白字符)。 |
以下是用于表達(dá)式中的一些典型語(yǔ)法符號(hào)及注釋:
正則表達(dá)式語(yǔ)法的特殊字符 | 功能 |
[] | 用于指定一個(gè)字符集,即可以匹配方括號(hào)內(nèi)的任意一個(gè)字符。字符集可以包含單個(gè)字符、多個(gè)字符、字符范圍等。 |
() | 一個(gè)捕獲組,用于將一組字符或模式捕獲并保存起來(lái),以便后續(xù)使用或匹配。捕獲組可以用于提取子字符串、進(jìn)行替換操作等。 |
- | 一個(gè)連字符,用于表示范圍或指定范圍。它可以用于字符集或重復(fù)次數(shù)的修飾符中。 |
^ | 在字符集中,^ 用于否定字符集;在斷言中,^ 用于表示行的開頭。 |
$ | 用于匹配字符串的結(jié)尾。 |
. | 匹配任意字符的元字符。可以匹配除了換行符( 、 )之外的任何字符。 |
* | 是一個(gè)限定符,用于指定前一個(gè)字符或子表達(dá)式出現(xiàn)的次數(shù)。它可以表示零次或多次。 |
+ | 是一個(gè)限定符,用于指定前一個(gè)字符或子表達(dá)式出現(xiàn)的次數(shù)。它可以表示一次或多次。 |
? | 是一個(gè)限定符,用于指定前一個(gè)字符或子表達(dá)式出現(xiàn)的次數(shù)。它可以表示零次或一次。 |
{n} | 是一個(gè)限定符,用于指定前一個(gè)字符或子表達(dá)式出現(xiàn)的次數(shù)。它表示前面的字符或子表達(dá)式必須精確出現(xiàn) n 次。 |
{n,m} | 是一個(gè)限定符,用于指定前一個(gè)字符或子表達(dá)式出現(xiàn)的次數(shù)范圍。其中,n 表示最小次數(shù),m 表示最大次數(shù)。 |
{n,} | 是一個(gè)限定符,用于指定前一個(gè)字符或子表達(dá)式出現(xiàn)的次數(shù)范圍,表示至少出現(xiàn) n 次。 |
是一個(gè)邊界斷言符,用于指定一個(gè)單詞的邊界。它匹配一個(gè)單詞的開頭或結(jié)尾,即前后都是非單詞字符(如空格、標(biāo)點(diǎn)符號(hào)等)的位置。 | |
B | 是一個(gè)邊界斷言符,與 相反。它匹配一個(gè)單詞內(nèi)部的位置,即前后都是單詞字符的位置。 |
d | 是一個(gè)字符類,用于匹配任意十進(jìn)制數(shù)字。等價(jià)于 [0-9]。 |
D | 是一個(gè)否定斷言符,用于匹配非數(shù)字字符。它是一個(gè)反向匹配符,用于與數(shù)字字符進(jìn)行區(qū)分。 |
w | 是一個(gè)元字符,用于匹配一個(gè)單詞字符。單詞字符包括字母、數(shù)字和下劃線 [a-zA-Z_0-9]。 |
W | 是一個(gè)反向字符斷言符,用于匹配非字母數(shù)字字符。 |
當(dāng)然,上面只是介紹了正則表達(dá)式的一些基礎(chǔ)知識(shí)。正則表達(dá)式具有很高的靈活性和可塑性,從簡(jiǎn)單的文本編輯器到復(fù)雜的開發(fā)工具,都可以使用正則表達(dá)式進(jìn)行文本處理。之前也提到了,又拍云 CDN 的邊緣規(guī)則功能就運(yùn)用到了正則表達(dá)式提取字符串,下面通過(guò)一些例子來(lái)了解一下它的強(qiáng)大之處。
正則表達(dá)式在又拍云CDN的應(yīng)用
示例一:目錄及參數(shù)改寫
將請(qǐng)求 URL 轉(zhuǎn)換為帶參數(shù)的動(dòng)態(tài) URL,例如請(qǐng)求的 URL 為:
http://example.com/pay/25/8/...
需要 CDN 邊緣節(jié)點(diǎn)轉(zhuǎn)換為如下請(qǐng)求:
http://example.com/pay.php?payid=25&categoryid=8...
這個(gè)時(shí)候,pattern 部分需要提取目錄數(shù)字,需要生成 $1 和 $2 這樣的變量,如下規(guī)則所示:
"rule": "/pay.php?productid=$1&categoryid=$2", "pattern": "^pay/([0-9]+)/([0-9]+)/(.*?).html$"
規(guī)則釋義:當(dāng)解析的 url 符合規(guī)則 ^pay/([0-9]+)/([0-9]+)/(.*?).html$,那么將請(qǐng)求導(dǎo)向到 /pay.php?productid=$1&categoryid=$2。
也即將 http://example.com/pay/25/8/...轉(zhuǎn)換為http://example.com/pay.php?payid=25&categoryid=8...
示例二:文件名改寫
pattern: /(.*)/playlist.m3u8$ rule: /$1'.m3u8'
規(guī)則釋義:當(dāng)訪問(wèn)地址為http://domain/app/stream/playlist.m3u8時(shí),將訪問(wèn)地址改寫為 http://domain/app/stream.m3u8。
應(yīng)用場(chǎng)景:在直播應(yīng)用場(chǎng)景中,因?yàn)榭蛻舳藱C(jī)制無(wú)法或者不方便升級(jí)的情況,可以通過(guò) URL 改寫,將 /stream/playlist.m3u8 改為 /stream.m3u8,其中 app 代表發(fā)布點(diǎn),stream 代表流名。
示例三:URL 限速
假如請(qǐng)求的 URL 為:http://test.example.com/mp4/4E10F356C0FEAD359C33DC5901307461-10.mp4 ,需要對(duì)該類型文件進(jìn)行限速,限速要求為:前 20MB 不限速,20MB 之后限速 800 KB/s,規(guī)則可這樣編寫:
"rule": "$WHEN($1, $EQ($_HOST, 'test.example.com'))$LIMIT_RATE_AFTER(20, m)$LIMIT_RATE(800, k)", "pattern": "^(/).+-10.mp4$"
規(guī)則釋義:當(dāng) $1 為真,且滿足請(qǐng)求 HOST 為 test.example.com 時(shí) ,開始 20MB 不限速,后面限制到 800KB/s。
又拍云 CDN 邊緣規(guī)則功能結(jié)合正則表達(dá)式,搭配處理操作,可以幫助您簡(jiǎn)化內(nèi)容分發(fā)業(yè)務(wù)邏輯,并提升終端用戶訪問(wèn)體驗(yàn)。該規(guī)則可以快速部署且配置簡(jiǎn)單,可極大降低業(yè)務(wù)實(shí)現(xiàn)成本。網(wǎng)站及 Web 應(yīng)用開發(fā)者或者安全工程師可以快速創(chuàng)建邊緣規(guī)則集來(lái)提升網(wǎng)站安全及分發(fā)性能。
最后,我來(lái)推薦一個(gè)好用的正則表達(dá)式匹配測(cè)試工具:https://regex101.com/,可以快速測(cè)試哪些字符串能匹配規(guī)則,搭配規(guī)則詳解,對(duì)于編寫和測(cè)試超級(jí)方便。
審核編輯:湯梓紅
-
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7122瀏覽量
125290 -
字符串
+關(guān)注
關(guān)注
1文章
589瀏覽量
21228 -
狀態(tài)機(jī)
+關(guān)注
關(guān)注
2文章
493瀏覽量
28156 -
編輯器
+關(guān)注
關(guān)注
1文章
821瀏覽量
31909 -
正則表達(dá)式
+關(guān)注
關(guān)注
0文章
28瀏覽量
3664
原文標(biāo)題:揭秘神秘的字符串匹配工具——正則表達(dá)式
文章出處:【微信號(hào):OSC開源社區(qū),微信公眾號(hào):OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
shell正則表達(dá)式學(xué)習(xí)
初識(shí) Python 正則表達(dá)式
深入淺出boost正則表達(dá)式
PHP正則表達(dá)式
關(guān)于java正則表達(dá)式的用法詳解
快速入門IPv6和正則表達(dá)式

Python正則表達(dá)式的學(xué)習(xí)指南

Python正則表達(dá)式指南

python正則表達(dá)式中的常用函數(shù)
Linux入門之正則表達(dá)式

shell腳本基礎(chǔ):正則表達(dá)式grep

評(píng)論