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