正規表示式(一)

HuDu發表於2022-08-20

一、基本字元

1.1、確定字元

一個最簡單的正規表示式,就是一組確定字元,如hello就是一個正規表示式,它會匹配下文中的hello
/hello
直接匹配內容

1.2、範圍字元

範圍字元,單個範圍字元只表示一個字元

字元 描述 相容性
.任意字元 除換行符外的任意單個字元 新增s修飾符,可以讓.包括換行符
\w單詞字元 字母、數字、下劃線任意單個字元。大寫\W表示非單詞字元 在python\w還可以表示漢字
\d數字 0-9任意單個數字。大寫\D表示非數字
\s空白字元 空格、tab製表符、換行都屬於空白字元。大寫\S非空白字元

1.3、自定義範圍字元[]

1.3.1、任意範圍[abc123]

例如小寫字母
[abcdefg一直到z]
注意,這裡只表示一個字母,是a~z其中的一個字母

1.3.2、區間範圍[0-9]

所有小寫字母簡寫方式如下
[a-z]
所有字母
[A-Za-z][A-z]

1.3.3、混合範圍

所有小些字母和數字
[a-z0-9]

[A-z\d_]等同於\w

[\d\D] 所有字元 不等於.  因為多了\n換行符

1.3.4、排除範圍集[^]

可以透過[]^取反符號進行組合
[^\d]表示所有的非數字 等同與\D
[^\D8-9] 表示排除所有非數字,以及89。等同於 [0-7]

1.3.5、範圍集中的特殊字元[.$^]

.表示任意字元,但在[.] 中它表示的是 . 字元本身。甚至是^-[] 範圍集本身語法,如果不是在恰當位置,也表示其字元本身。為避免混淆建議大家在範圍集中匹配特殊字元時,統一加上 轉義符 \。 如 [\^\.] 表示匹配 ^.

Java 中的特殊用法,例如匹配車牌號,車牌號中為了防止混淆,沒有IO
[\w&&[^IO]],即匹配單詞和數字並且排除掉 I 和 O
等同於[A-HJ-NP-z]

1.3.6、轉義特殊符\

例如,如果要匹配^符號,使用/\^進行匹配

二、邏輯控制指令

邏輯符 描述
如hi|hello|hellow 匹配其中一個單詞即可。
()子表示式 用於獨立計算括號中的內容。如:(張|李)建國 表示第一個字元是張或者李。
{}數量控制 對字元或字表示式的數量範圍進行限定。如:張.{1,3} 表示“張”後面只能跟1到3個任意字元。

2.1、基本邏輯控制

2.1.1、|

# 表示第一個字元為 a 或者 b
/a|b
等同於
[ab]

在 Unix 中的使用

由於 | 在類Unix系統中是特殊字元,當你使用grepvim 進行正則搜尋時,必須進行轉義

grep '401\|403\|404\|500' nginx.access.log

在vim 中輸入/ 開始正則搜尋,同樣|需要轉義

/401\|403\|404|500

2.1.2、()巢狀子表示式

與程式設計中的括號作用類似 如 `(1+2)*3=9` ,它們都是把一段邏輯進行拆分獨立運算,再組合一起。如`(www|mvn|test).coderead.cn` 表示子域名為www、mvn、test任意一個。這裡子域名就是一個**子表示式**會將()內的語句作為一個整體進行匹配
例如
/(http|https)://.*
就會匹配所有 http://.* 和 https://.*
子表示式支援巢狀,如:(www|mvn|test-(bj|sz|gz|sh)).coderead.cn 表示 test子域名又可繼續拆分為test-bj、test-sz、test-sh、test-gz。

除此之外()還可以表示分組和邊界斷言

()[]的區別

# 表示第一個字元是 abc123 其中的一個
/[abc|123]
# 表示匹配 abc 或者 123
/(abc|123)

2.2、數量控制{}

邏輯符 描述
{n} 指定數量 匹配n個字元
{n,m} 指定範圍 匹配n至m個字元,即至少n個,最多m個。
{n,} n個及以上 匹配n個或者n個以上字元
* 任意個 相當於{0,} 0個或無數個
+ 至少1個 相當於 {1,}
? 0或1個 相當於 {0,1}

2.2.1、{n} 指定數量

數量控制作用於字元或子表示式,已限制其數量範圍。\d{6}表示必須是6位數字。請注意:一個{}僅作用於其前面的單個字元如:hi{2} 表示hii,而不是hihi。

2.2.2、{n,m} 指定範圍

# 表示 2 個到 9 個字元
/\w{2,9}

2.2.3、{n,} 指定最小值

# 表示 2 個以上的字元
/\w{2,}

2.2.4、{} 作用於子表示式

2.2.5、*+? 量詞簡寫

* 表示 {0,}0 到無窮大個
+ 表示 {1,}1 個以上包含 1? 表示 {0,1}01

2.2.6、?最少化匹配(懶惰匹配)

對於一個字串
<span>hello</span> <span>hello</span>

/<span>.*</span> 會直接匹配整個字串,預設是最大化匹配,如果想分開匹配可以使用下面
/<span>.*?</span> 實現最小化匹配

預設匹配的原理,對於 /<span>.*</span> 正則匹配
1. <span> 會匹配字串的<span>
2. . 會匹配除換行外的所有字元
3. * 會匹配到字串末尾
4. </span> 正則會進行回退,直到退到與 </span> 匹配
所以預設為最大匹配

如果是增加了 ?
會回退到最先的 </span>

所以效能的話,是預設的最大化匹配最高。

總結

?表示最小化匹配,也叫懶惰匹配,只能用在量詞後面,表示如果多個文字段同時滿足條件,則匹配最短的。?可以用在所有量詞後面,甚至是?? ,但這個量詞不能是固定的值,如:hel{2}?o 這是沒有意義的。因為它不存在最少和最多。
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章