1. 程式人生 > >正則表達式知識詳解

正則表達式知識詳解

增加 全局 name 示例 列表 regexp 發現 txt cli

一、什麽是正則表達式?

1.定義:

正則表達式(regular expression)描述了一種字符串匹配的模式,可以用來檢查一個串是否含有某種子串、將匹配的子串做替換或者從某個串中取出符合某個條件的子串等。構造正則表達式的方法和創建數學表達式的方法一樣。也就是用多種元字符與運算符可以將小的表達式結合在一起來創建更大的表達式。正則表達式的組件可以是單個的字符、字符集合、字符範圍、字符間的選擇或者所有這些組件的任意組合。

2.組成:

正則表達式是由普通字符(例如字符 a 到 z)以及特殊字符(稱為"元字符")組成的文字模式。模式描述在搜索文本時要匹配的一個或多個字符串。正則表達式作為一個模板,將某個字符模式與所搜索的字符串進行匹配。

3.何時使用:驗證——從頭到尾完整匹配!

查找——只要部分匹配即可!

二、正則表達式的基本語法和規則

1.備選字符集:規定某*一位字符*可用的備選字符的集合

語法:[可選字符列表]

強調:1. 無論備選字符集包含多少字符,只能選1個

2. 必須選1個!

比如:6位數字的密碼

[0123456789][0123456789][0123456789][0123456789][0123456789][0123456789]

簡化:1. 當備選字符連續時,可用-表示範圍的區間

比如:[0123456789]-->[0-9]

[0-9][0-9][0-9][0-9][0-9][0-9]

[a-z]-->1位小寫字母

[A-Z]-->1位大寫字母

[A-Za-z]-->1位字母,大小寫都行

[0-9a-zA-Z]-->1位字母或數字都行

反選:[^不能選的字符列表]

比如:[^47] 強調:^作“除了”使用時,只能放在開頭

2. 預定義字符集:為常用的字符集專門提供的簡化寫法!

“\d”-->[0-9]-->1位數字

“\w”-->[0-9a-zA-Z_]-->1位字母,數字或_

“\s”-->1位空字符:匹配任何空白字符,包括空格、制表符、換頁符等等。等價於 [ \f\n\r\t\v]。

“ . “: 除換行回車外的任何一個字符,如:

"a.[0-9]":表示一個字符串有一個"a"後面跟著一個任意字符和一個數字;
"^.{3}$":表示有任意三個字符的字符串(長度為3個字符)

\t--------匹配一個制表符

預定義字符的反義:預定義字符的大寫形式都是小寫的反義

\D---->1位非數字字符

\S------匹配任何非空白字符。等價於 [^\f\n\r\t\v]。

\v------匹配一個垂直制表符

\n------匹配一個換行符

\r-------匹配一個回車符

3. 數量詞:規定相鄰的字符集可出現的次數

確定數量:3種:

{n}--> 必須反復出現n位

{n,m}--> 最少出現n次,最多出現m次

{n,}-->至少出現n次,多了不限!

比如:/^\d{6}$/——6位數字

手機號規則:

第1位:只能是1

第2位:[34578]

第3位之後,必須是9位數字

手機號:/^1[34578]\d{9}$/

不確定數量:3種:

*: 有沒有都行,次數不限,相當於{0,}

+: 至少1次,重復次數不限,相當於{1,}

?: 有沒有都行,最多1次,相當於{0,1}

():分組

|: 左右兩正則表達式選其一

身份證號邏輯:

前15位數字

16,17位必須是數字

最後一位可以是數字或X x

後三位 可有可無,如果有,只能出現一次

\d{15}(\d\d[0-9Xx])?

手機號:

手機號前可能出現+86或0086。

前綴可有可無,且只能出現一次

前綴和手機號之間可以有或沒有任意個空字符

   第1位:只能是1

第2位:[34578]

第3位之後,必須是9位數字

手機號:

(\+86|0086)?\s*1[34578]\d{9}

4. 指定匹配位置

^表達式: 必須以表達式的規則為開頭

表達式$: 必須以表達式的規則為結尾

比如:選擇字符串開頭的空格?^\s*

選擇結尾空格?\s*$

選擇開頭或結尾的空格?^\s*|\s*$

*預告:今後只要在程序中執行驗證:都要前加^後加$*

表示從頭到尾完整匹配。

比如:test():

^\d{6}$——從頭到尾必須只能是6位數字

1234567

5. 預判:在正式匹配正則表達式之前,先預讀整個字符串,進行初步匹配,如果預判都未通過,則不再驗證!

1)(?=表達式): 先瀏覽字符串是否滿足表達式的要求

何時使用:只要正則中出現類似"而且"

比如:4位數字,但不能包含4和7

(?=[^47]$) 是否由除了4,7之外的字符組成

2)(?!表達式):先檢查字符串是否不滿足表達式要求

   比如:6位以上密碼。

字母,數字組成

首字母不能是數字: [a-zA-Z][a-zA-Z0-9]{5,}

必須至少包含1個大寫字母

不能都由小寫字母和數字組成: (?![a-z0-9]+$)

必須至少包含1個數字

不能都由小寫字母和大寫字母組成:

(?![a-zA-Z]+$)

6.特殊字符

  所謂特殊字符,就是一些有特殊含義的字符,如"*.txt"中的*,簡單的說就是表示任何字符串的意思。如果要查找文件名中有*的文件,則需要對*進行轉義,即在其前加一個\。ls \*.txt。許多元字符要求在試圖匹配它們時特別對待。若要匹配這些特殊字符,必須首先使字符"轉義",即,將反斜杠字符 (\) 放在它們前面。下面列出了正則表達式中的特殊字符:(請註意在方括號中,不需要轉義字符。)

“$”------匹配輸入字符串的結尾位置。如果設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 ‘\n‘ 或 ‘\r‘。要匹配 $ 字符本身,請使用 \$。

“()”----標記一個子表達式的開始和結束位置。子表達式可以獲取供以後使用。要匹配這些字符,請使用 \( 和 \)。

“*”----匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。

“+”-----匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。

“.”----匹配除換行符 \n之外的任何單字符。要匹配 .,請使用 \.。

“[”------標記一個中括號表達式的開始。要匹配 [,請使用 \[。

“?”----匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?。

“\”----將下一個字符標記為或特殊字符、或原義字符、或向後引用、或八進制轉義符。例如, ‘n‘ 匹配字符 ‘n‘。‘\n‘ 匹配換行符。序列 ‘\\‘ 匹配 "\",而 ‘\(‘ 則匹配 "(".

“^”-----匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。要匹配 ^ 字符本身,請使用 \^。

“{”----標記限定符表達式的開始。要匹配 {,請使用 \{。

“|”----指明兩項之間的一個選擇。要匹配 |,請使用 \|。

7. 貪婪模式和懶惰模式

貪婪模式:默認情況下,正則表達式會匹配最大的符合條件的字符串, *、+和?限定符都是貪婪的,因為它們會盡可能多的匹配文字,只有在它們的後面加上一個?就可以實現非貪婪或最小匹配。

貪婪模式原因:(.*) (.+)

懶惰模式:正則表達式僅匹配最小的符合規則的字符串

比如:篩選網頁中的a元素:

<a\s+(.*)href\s*=\s*["‘]([^‘"]*)["‘]

貪婪模式-->懶惰模式:.*?

例如:

您可能搜索 HTML 文檔,以查找括在 H1 標記內的章節標題。該文本在您的文檔中如下:

<h1> Chapter 1 - Introduction to Regular Expression</h1>

下面的表達式匹配從開始小於符號 (<) 到關閉 H1 標記的大於符號 (>) 之間的所有內容。

/<.*>/

如果您只需要匹配開始 H1 標記,下面的"非貪心"表達式只匹配 <H1>。

/<.*?>/

通過在 *、+ 或 ? 限定符之後放置 ?,該表達式從"貪心"表達式轉換為"非貪心"表達式或者最小匹配。

三、常用正則表達式示例及說明:

1.正則表達式驗證控制文本框的輸入字符類型

1)只能輸入數字和英文的:

<input onkeyup="value=value.replace(/[\W]/g,‘‘) " onbeforepaste="clipboardData.setData(‘text‘,clipboardData.getData(‘text‘).replace(/[^\d]/g,‘‘))" ID="Text1" NAME="Text1">

2)只能輸入數字的:

<input onkeyup="value=value.replace(/[^\d]/g,‘‘) " onbeforepaste="clipboardData.setData(‘text‘,clipboardData.getData(‘text‘).replace(/[^\d]/g,‘‘))" ID="Text2" NAME="Text2">

3)只能輸入全角的:

<input onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,‘‘)" onbeforepaste="clipboardData.setData(‘text‘,clipboardData.getData(‘text‘).replace(/[^\uFF00-\uFFFF]/g,‘‘))" ID="Text3" NAME="Text3">

4)只能輸入漢字的:

<input onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,‘‘)" onbeforepaste="clipboardData.setData(‘text‘,clipboardData.getData(‘text‘).replace(/[^\u4E00-\u9FA5]/g,‘‘))" ID="Text4" NAME="Text4">

2.正則表達式的應用實例通俗說明

*******************************************************************************

//校驗是否全由數字組成

/^[0-9]{1,20}$/

^ 表示打頭的字符要匹配緊跟^後面的規則

$ 表示打頭的字符要匹配緊靠$前面的規則

[ ] 中的內容是可選字符集

[0-9] 表示要求字符範圍在0-9之間

{1,20}表示數字字符串長度合法為1到20,即為[0-9]中的字符出現次數的範圍是1到20次。
/^ 和 $/成對使用應該是表示要求整個字符串完全匹配定義的規則,而不是只匹配字符串中的一個子串。
*******************************************************************************

//校驗登錄名:只能輸入5-20個以字母開頭、可帶數字、“_”、“.”的字串

/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/

^[a-zA-Z]{1} 表示第一個字符要求是字母。

([a-zA-Z0-9]|[._]){4,19} 表示從第二位開始(因為它緊跟在上個表達式後面)的一個長度為4到9位的字符串,它要求是由大小寫字母、數字或者特殊字符集[._]組成。

*******************************************************************************

//校驗用戶姓名:只能輸入1-30個以字母開頭的字串

/^[a-zA-Z]{1,30}$/

*******************************************************************************

//校驗密碼:只能輸入6-20個字母、數字、下劃線

/^(\w){6,20}$/

\w:用於匹配字母,數字或下劃線字符

*******************************************************************************

//校驗普通電話、傳真號碼:可以“+”或數字開頭,可含有“-” 和 “ ”

/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/

\d:用於匹配從0到9的數字;

“?”元字符規定其前導對象必須在目標對象中連續出現零次或一次

可以匹配的字符串如:+123 -999 999 ; +123-999 999 ;123 999 999 ;+123 999999等

*******************************************************************************

//校驗URL

/^http[s]{0,1}:\/\/.+$/ 或 /^http[s]{0,1}:\/\/.{1,n}$/ (表示url串的長度為length(“https://”) + n )

\ / :表示字符“/”。

. 表示所有字符的集

+ 等同於{1,},就是1到正無窮吧。

*************************************************************************

三、RegExp 對象和方法

在Javascript中,通過RegExp對象來支持正則表達式。創建正則表達式的方式有兩種:

1.最簡單的創建正則表達式的方法:字面量形式

Var expression=/pattern/flags

其中pattern部分可以使任何簡單的正則表達式

Flags表示正則表達式的標誌,正則表達式的匹配模式支持3個標誌:

1)”g”:表示全局(globle)模式,即模式被應用於所有字符串,而非在發現第一個匹配項是立即停止。

2)“i”:表示不區分大小寫模式,即在確定匹配項是忽略模式於字符串的大小寫。

3)“m”:表示多行模式,即在到達一行文本末尾是還會繼續查找下一行中是否存在與模式匹配的項。例如:

/*匹配字符串中所有”at”的實例*/

Var paatern1=/at/g;

/*匹配第一個”bat”或”cat”,不區分大小寫*/

Var paatern2=/[bc]at/i;

/*匹配所有以”at”結尾的3個字符串的組合,不區分大小寫*/

Var paatern2=/.at/gi;

2.使用RegExp構造函數創建正則表達式

Var expression=new Regexp([bc]at,i);

其中傳給RegExp構造函數的兩個參數都是字符串(不能把正則表達式的字面量傳遞給RegExp構造函數),也因此,在某些情況下要對字符進行雙重轉義。所有的元字符都必須進行雙重轉義。例如:

字面量模式:

/\[bc\]at/ /\.at/ /name\/age/ /\d.\d{1,2}/ /\w\\hello\\123/

等價的字符串形式:

“\\[bc\\]at” “\\.at” “name\\/age” “\\d.\\d{1,2}” “\\w\\\\hello\\\\123”

註意:使用正則表達式字面量和使用RegExp構造函數創建的正則表達式不一樣,正則表達式字面量始終會共享同一個RegExp實例,而構造函數創建的每一個新RegExp實例都是一個新實例(動態創建的)。

3.Exec() 查找方法

Exec()接受一個參數,即要應用模式的字符串,然後返回包含第一個匹配項的信息的數組,如果沒有找到則返回null。返回的數組包含兩個屬性:index和input,index表示匹配項在字符串中的位置,input表示應用正則表達式的字符串。

對於exec()而言即使在模式中設置了全局模式(g),它每次也只會返回一個匹配項,但是如果設置了全局模式,每次調用它都會返回字符串中的下一個匹配項,知道搜索到字符串的末尾為止。所以自全局匹配模式下,lastIndex的值在每次調用exec()後,都會增加,所以要想獲取所有的匹配項內容和下標,需要循環獲取。而在非全局模式下lastIndex則始終不變。

4.test()驗證方法

此方法要求驗證的字符串和正則表達式從頭到尾完全匹配,需要”^”和”$”符號。

Reg.test(str): 如果匹配,返回true,否則返回false。Test()方法經常被用在if語句中,經常被用在驗證用戶輸入的情況下,驗證用戶輸入是不是有效。

例如:

Var text=”000-00-0000”;

Var pattern=/\d{3}-\d{2}-\d{4}/;

If(pattern.test(text)){

Atert(“the pattern was matched”);

}

正則表達式知識詳解