Utilo

雷傑克斯作弊表:模式,標誌和現實實中的例子

一個實用的正規表示式作弊表格,包含字元類,量化器,,組,周圍檢視,標誌和日常任務的測試模式。

· 6 分鐘閱讀

常用表示式是描述文字的緊語言。一行可以驗證輸入,從日誌中提取資料或更名數百個檔案。它們的語法很密集,。這張作弊表收集了你每天使用的語法,解釋了讓人們陷入困境的部分,。所有的示例都使用JavaScript語法,它也非常接近Python,Java,Go和.NET。

在閱讀過程中,在regex測試 中嘗試每個模式;看到突出匹配是建立直覺的最快方法。

字面上的字元和逃跑

大多數字符都匹配自己:cat匹配"貓"。十二個字元具有特殊的含義,

. * + ? ^ $ { } ( ) | [ ] \ /

所以3.14匹配"3.14",同時也匹配"3x14",而3\.14只匹配"3.14"。

字元類

圖案 匹配
. 任何字元除了新行 (除非設定了s標誌)
\d 一個數字09
\w 一個字元:字母,數字或下劃線
\s 白空間:空格,選項卡,新行
\D, \W, \S 對於上述情況而言,
[abc] 一個a,b或c
[a-z] 任何小寫的ASCII字母
[^0-9] 不是數字的任何字元
\p{L} 任何文字 (需要u標誌)

在方形括號內,大多數特殊字元失去了它們的意義。[.]與一個字面點相匹配。一個線條是字面上的,當放在第一個或最後一個:[-a-z]。

數量表

圖案 意義
a* 零或以上
a+ 一個或多個
a? 零或一個 (可選)
a{3} 準確的三個
a{2,5} 在兩到五之間
a{2,} 兩個或更多

量化器是貪的:它們儘可能地匹配,然後回溯。增加?會讓他們變得惰。鑑於<b>bold</b>,模式<.+>匹配整個字串,而<.+?>只匹配<b>。

和邊界

  • ^匹配字串的開始,或者每個線的m標誌。
  • $匹配字串的末尾,或者每個行與 m匹配。
  • \b 匹配一個字元邊界:字元和非字元之間的位置。

\bcat\b與"貓坐著"中的"貓"相匹配,。是驗證必不可少的:\d{5}在"abc123456"中任何地方都會找到五個數字,而^\d{5}$則要求整個輸入都必須是五個數字。

組和交替

  • (abc) 集團和捕獲。捕獲的文字可用為 $1,$2 替換。
  • 沒有捕獲的(?:abc)組,這更快,保持清潔的編號。
  • (?<year>\d{4})是一個命名的群體,可以用match.groups.year來訪問。
  • a|b與A或B相匹配。交替是最低的優先順序,所以^cat|dog$意味著"從貓開始"或"從狗結束"。用^(?:cat|dog)$來匹配一個字。
  • \1是對第1組的回顧:(\w)\1在"hello"中發現了雙重字母,比如ll。

周圍看看

周圍觀察者聲稱,沒有消耗字元,某種東西是否與當前位置相鄰。

圖案 意義
(?=...) 積極的預警:接著是
(?!...) 負面的預警:沒有其後的
(?<=...) 積極的後視:前面是
(?<!...) 負面後視:沒有前面的

例如:\d+(?=px)匹配"16px"中的數字,沒有"px";(?<=\$)\d+匹配美元符號後的數量;^(?!.*password).*$匹配沒有包含"密碼"的行。

旗

  • g (全球):找到所有匹配,而不是停留在第一個。
  • i (忽略大小寫):a匹配"A"。
  • m (多行):^和$線上斷時匹配。
  • s (dotAll):.也符合新線。
  • u (單碼):將像表情符號這樣的程式碼物件視為單個字元,並啟用 \p{...}。
  • y (粘性):只在最後一場比賽結束的位置進行匹配。

日常任務的模式

它們是實用的,而不是詳盡的。實際驗證應與伺服器端檢查相結合。

電子郵件 (務實的):

^[^\s@]+@[^\s@]+\.[^\s@]{2,}$

捕獲失蹤@或域名等字型錯誤;唯一真正的驗證是傳送確認電子郵件。

標籤:

^[a-z0-9]+(?:-[a-z0-9]+)*$

ISO日期 (年年至月日):

^(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])$

這檢查形狀和範圍,但不是是否存在2月31日;解析日期以確認。

標籤:

^#(?:[0-9a-fA-F]{3}){1,2}$

IPv4地址:

^(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)$

語義版本:

^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[\w.-]+)?(?:\+[\w.-]+)?$

強密碼檢查 (至少12個字元,一個小字母,一個大字母,一個數字):

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$

**切割空白:**用空字串替換^\s+|\s+$ (以g)。

** 縮小重複的空格:** 取代 {2,}一個空格。

從日誌行中提取key=value對:

(\w+)=("[^"]*"|\S+)

**camelCase到snake_case:**用$1_$2替換([a-z0-9])([A-Z]),然後小寫結果。更多關於命名風格的資訊,請參閱 [駝案例與蛇案例] (http://blog/naming-conventions-camelcase-snake-case)。

效能和災難性追溯

在JavaScript,Python和Java中使用的Regex引擎使用了回溯。一些模式迫使發動機在幾乎匹配的輸入中嘗試指數式數量的組合。典型的例子是^(a+)+$對陣"aaaaaaaaaaaaaaaaaaaa!"。每個額外的"a"都會使工作翻倍,

為了避免這種情況:

  • 不要將量化符嵌入相同的字元上,例如(a+)+或(\w*)*。
  • 讓替代方案相互排斥:(a|ab)*是有風險的;重組它。
  • 偏好特定類別而不是.*:"[^"]*"比".*?"更安全,更快。
  • 在匹配不可靠資料之前限制輸入長度。

可讀性提示

  • 逐步構建複雜的圖案,並測試每一塊。
  • 使用命名組,以便程式碼讀取m.groups.month而不是m[2]。
  • 在程式碼中評論複雜的模式,或者從更小的字串中構建它們。
  • 如果一個模式需要不止一兩行,考慮一個小的解析器是否更清楚。

總結

學習核心類,量化器,,組和標誌,。使用惰量化器和據,在需要背景時尋找周圍,不要消耗它,注意巢狀量化器,並在傳送模式之前始終對匹配和不匹配的示例進行測試。

本頁內容由英文自動翻譯而來,如發現錯誤,歡迎告訴我們。

相關指南