學習正規表示式的時候,可以說正則並不是很難,但是就是老記不住語法規則,相信大家跟我也有同樣的發現吧,但是沒辦法,需要耐心的東西只能多啃幾遍了。
正規表示式的作用
- 資料驗證。
- 複雜的字串搜尋、替換。
- 基於模式匹配從字串中提取子字串。
概述
正規表示式包括普通字元(例如,a 到 z 之間的字母)和特殊字元(稱為“元字元”)。
若要匹配這些特殊字元,必須首先轉義字元,即,在字元前面加反斜槓字元 \
**。
例如,若要搜尋 “+”文字字元,可使用表示式 \+
。
但是大多數 特殊字元 在中括號表示式內出現時失去本來的意義,並恢復為普通字元。
建構函式
可使用字面量也可以用內建的建構函式:
var regex = new RegExp('xyz', 'i');
var regex = new RegExp(/xyz/i);
var regex = /xyz/i; 複製程式碼
有一種情況要注意:就是如果正則中出現了反斜槓 “\”
,在用建構函式時建立正則物件時,要轉義,
比如: re = new RegExp("\\w+")
// 這裡的 \ 要轉義,re = /\w+/
// 這樣就不需要轉義;
用於模式匹配的String方法
- String.search()
引數:要搜尋的子字串,或者一個正規表示式。
返回:第一個與引數匹配的子串的起始位置,如果找不到,返回-1。
說明:不支援全域性搜尋,如果引數是字串,會先通過RegExp建構函式轉換成正規表示式。如:var str="i am jay"; var res=str.search("jay"); console.log(res); //5 console.log(str.search("hz"); //-1複製程式碼
- String.replace(),個人認為是正則中最強大的api
作用:查詢並替換字串。
第一個引數:字串或正規表示式,
第二個引數:要進行替換的字串,也可以是函式。
用法:
當第二個引數是字串時,替換文字中的$字元有特殊含義:
屬性 | 描述 |
$1,$2,…,$99 | 匹配第 1-99 個 分組裡捕獲的文字 |
$& | 匹配到的子串文字 |
$` | 匹配到的子串的左邊文字 |
$' | 匹配到的子串的右邊文字 |
$$ | 美元符號 |
如:
'abc'.replace(/b/g, "{$$$`$&$'}")
// 結果為 "a{$abc}c",即把b換成了{$abc}複製程式碼
"1234 2345 3456".replace(/(\d)\d{2}(\d)/g, function (match, $1, $2, index, input) {
console.log([match, $1, $2, index, input]);
});
// => ["1234", "1", "4", 0, "1234 2345 3456"]
// => ["2345", "2", "5", 5, "1234 2345 3456"]
// => ["3456", "3", "6", 10, "1234 2345 3456"] 複製程式碼
- String.match()
引數:要搜尋的子字串,或者一個正規表示式。
返回:一個由匹配結果組成的陣列。與是否有修飾符g有關
非全域性檢索:如果沒有找到任何匹配的文字返回null;否則陣列的第一個元素是匹配的字串,剩下的是小括號中的子表示式,即a[n]中存放的是$n的內容。非全域性檢索返回三個屬性:length 屬性;index 屬性宣告的是匹配文字的第一個字元的位置;input 屬性則存放的是被檢索的字串 string。
全域性檢索:設定標誌g則返回所有匹配子字串,即不提供與子表示式相關的資訊。沒有 index 屬性或 input 屬性。
如:
var string = "2017.06.27";
var regex1 = /\b(\d+)\b/;
var regex2 = /\b(\d+)\b/g;
console.log( string.match(regex1) );
console.log( string.match(regex2) );
// => ["2017", "2017", index: 0, input: "2017.06.27"]
// => ["2017", "06", "27"]
複製程式碼
- String.split(),個人經常用到的一個api,簡單實用
作用:把一個字串分割成字串陣列,改變原字串,與陣列方法join對應
引數:正規表示式或字串,可以有第二個引數,表示結果陣列的最大長度 ,並且當正則使用分隔符時結果陣列中是包含分隔符的。
返回:子串組成的陣列。
RegExp的方法
- RegExpObject.exec(),比match強大
引數:字串。
返回:
非全域性檢索:與String.macth()非全域性檢索相同,返回一個陣列或null。
全域性檢索:儘管是全域性匹配的正規表示式,但是exec方法只對指定的字串進行一次匹配。但是可以反覆呼叫來實現全域性檢索。在 RegExpObject 的lastIndex 屬性指定的字元處開始檢索字串;匹配後,將更新lastIndex為匹配文字的最後一個字元的下一個位置;再也找不到匹配的文字時,將返回null,並把 lastIndex 屬性重置為 0。
var string = "2017.06.27";
var regex2 = /\b(\d+)\b/g;
var result;
while ( result = regex2.exec(string) ) {
console.log( result, regex2.lastIndex );
}
// => ["2017", "2017", index: 0, input: "2017.06.27"] 4
// => ["06", "06", index: 5, input: "2017.06.27"] 7
// => ["27", "27", index: 8, input: "2017.06.27"] 10
複製程式碼
RegExpObject.test(),匹配字串
引數:字串。
返回:true或false。RegExpObject.toString()
返回:字串
這兩個較簡單,就不多講了。
字元
|
指示在兩個或多個項之間進行選擇。類似js中的或,又稱分支條件。/
正規表示式模式的開始或結尾。\
反斜槓字元,用來轉義。-
連字元 當且僅當在字元組[]的內部表示一個範圍,比如[A-Z]就是表示範圍從A到Z;如果需要在字元組裡面表示普通字元-,放在字元組的開頭或者尾部即可。
.
匹配除換行符 \n 之外的任何單個字元。\d
等價[0-9],匹配0到9字元。\D
等價[^0-9],與\d
相反。 \s
匹配空白符。與\S
相反
\w
與以下任意字元匹配:A-Z、a-z、0-9 和下劃線,等價於 [A-Za-z0-9]。
\W
與\w相反,即 [^A-Za-z0-9]限定符(量詞字元)
顯示限定符位於大括號 {} 中,幷包含指示出現次數上下限的數值;*+?
這三個字元屬於單字元限定符:
{n}
正好匹配 n 次。{n,}
至少匹配 n 次。{n,m}
匹配至少 n 次,至多 m 次。*
等價{0,}+
等價{1,}?
等價{0,1}
注意:
- 顯示限定符中,逗號和數字之間不能有空格,否則返回null!
- 貪婪量詞
*
和+
:javascript預設是貪婪匹配,也就是說匹配重複字元是儘可能多地匹配。 - 惰性(最少重複匹配)量詞
?
:當進行非貪婪匹配,只需要在待匹配的字元後面跟隨一個?
即可。如:var reg = /a+/; var reg2 = /a+?/; var str = 'aaab'; str.match(reg); // ["aaa"] str.match(reg2); // ["a"]複製程式碼
定位點(錨字元、邊界)
^
匹配開始的位置。將 ^
用作括號[]
表示式中的第一個字元,則會對字符集求反。$
匹配結尾的位置。\b
與一個字邊界匹配,如er\b 與“never”中的“er”匹配,但與“verb”中的“er”不匹配。\B
非邊界字匹配。
標記
中括號
[]
字元組;標記括號表示式的開始和結尾。[...]
匹配方括號內任意字元。很多字元在[]
都會失去本來的意義:[^...]
匹配不在方括號內的任意字元;[?.]
匹配普通的問號和點號。
注意:反斜槓字元\
在[]
中仍為轉義字元。若要匹配反斜槓字元,請使用兩個反斜槓\\
。
另外不要濫用字元組這個失去意義的特性,比如不要使用[.]
來代替\:
轉義點號,因為需要付出處理字元組的代價。大括號
{}
標記限定符表示式的開始和結尾。小括號
()
標記子表示式的開始和結尾,主要作用是分組,對內容進行區分。
(模式)
可以記住和這個模式匹配的匹配項(捕獲分組)。不要濫用括號,如果不需要儲存子表示式,可使用非捕獲型括號(?:)
來進行效能優化。(?:模式)
與模式 匹配,但不儲存匹配項(非捕獲分組)。(?=模式)
零寬正向先行斷言,要求匹配與模式 匹配的搜尋字串。 找到一個匹配項後,將在匹配文字之前開始搜尋下一個匹配項;但不會儲存匹配項。(?!模式)
零寬負向先行斷言,要求匹配與模式 不匹配的搜尋字串。 找到一個匹配項後,將在匹配文字之前開始搜尋下一個匹配項;但不會儲存匹配項。
可能會有點難懂,不過沒關係,來幾個例子就知道啥意思了
如下為捕獲和非捕獲分組區別:
'13588884444'.replace(/(\d{3})(\d{4})(\d{4})/g, '$1****$3')
//=> "135****4444"
'13588884444'.replace(/(\d{3})(?:\d{4})(\d{4})/g, '$1****$2')
//=> "135****4444"
複製程式碼
先行斷言(?=模式)
:x只有在y前面才匹配,必須寫成/x(?=y)/
。 解釋:找一個x,那個x的後面有y。
先行否定斷言(?!模式)
: x只有不在y前面才匹配,必須寫成/x(?!y)/
。 解釋:找一個x,那個x的後面沒有y。
如:對其後緊跟 "all" 的 "is" 進行全域性搜尋:
var str="Is this all there is";
var patern=/is(?= all)/g;
console.log(str.match(pattern)); //["is"]複製程式碼
var s = "i am jay";
var p = /j(?!ay)/g;
s.match(p)
//null
複製程式碼
- 反向引用:主要作用是給分組加上識別符號\n。
\n
表示引用字元,與第n個子表示式第一次匹配的字元相匹配。
反向引用的例子,如要寫一個正則支援匹配如下三種格式:
2016-06-12
2016/06/12
2016.06.12
最先可能想到的正則是:
var regex = /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/;
複製程式碼
其中 / 和 . 需要轉義。雖然匹配了要求的情況,但也匹配 "2016-06/12" 這樣的資料。
假設我們想要求分割符前後一致怎麼辦?此時需要使用反向引用:
var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // true
console.log( regex.test(string4) ); // false
複製程式碼
注意裡面的 \1,表示的引用之前的那個分組 (-|\/|\.)。不管它匹配到什麼(比如 -),\1 都匹配那個同樣的具體某個字元。
我們知道了 \1 的含義後,那麼 \2 和 \3 的概念也就理解了,即分別指代第二個和第三個分組。
優先順序順序
\
轉義符(), (?:), (?=), []
括號和中括號*、+、?、{n}、{n,}、{n,m}
限定符- 任何元字元
^、$、\
定位點和序列 |
替換
實踐
看完介紹內容後可以看看以下的例子,歡迎大佬們在評論區給出答案指定!!!
- 匹配 16 進位制顏色值
#ffbbad
#Fc01DF
#FFF
#ffE
2.匹配時間
以 24 小時製為例。
要求匹配:
23:59
02:07
3.匹配日期
比如 yyyy-mm-dd 格式為例。要求匹配:
2017-06-10
4.匹配 id
要求從
<div id="container" class="main"></div>提取出 id="container"。
5.數字的千位分隔符表示法
比如把 "12345678",變成 "12,345,678"。可見是需要把相應的位置替換成 ","。
6.字串 trim 方法模擬
trim 方法是去掉字串的開頭和結尾的空白符。7.匹配成對標籤
要求匹配:
<title>regular expression</title>
<p>laoyao bye bye</p>
不匹配:
<title>wrong!</p>
8.將形如"a=1&b=2&a=3&b=4"
的字串壓縮為"a=1,3&b=2,4"
,(用replace)
9.test整體匹配某個字串
10.IPV4 地址(優先順序知識點)
歡迎大佬們在評論區給出答案指定!!!,如想知道解析的也可在評論區提出。