在JavaScript中,正則表達式由RegExp對象表示。RegExp對象呢,又能夠經過直接量和構造函數RegExp兩種方式建立,分別以下:html
//直接量 var re = /pattern/[g | i | m];
//構造函數 var re = new RegExp(["pattern", ["g" | "i" | "m"]]);
其中,末尾的可選字符(g、i和m)分別表示:正則表達式
g: 模式執行一個全局匹配。簡而言之,就是找到全部匹配,而不是在找到第一個以後就中止。數組
i: 模式執行不區分大小寫的匹配。函數
m: 多行模式,^和$錨除了匹配字符串的開頭和結尾外,還匹配每行的開頭和結尾。例如,模式/Java$/m匹配"Java"和"Java\nScript"。測試
基礎篇 |
--特殊字符--spa
在正則表達式中,全部的字母字符和數字均可以按照直接量與自身匹配,如/JavaScript/匹配的就是字符串"JavaScript",可是有些特殊字符呢?如換行符。因此在JavaScript中規定以反斜槓(\)開頭的轉義序列支持這些特殊字符。經常使用的特殊字符以下:code
轉義字符htm |
匹配對象 |
\nblog |
換行符 |
\r |
回車 |
\f |
換頁符 |
\t |
製表符 |
\v |
垂直製表符 |
--字符類--
在正則表達式中,假若將單獨的字符放入方括號([ ])中,就能夠組合成字符類。應用到匹配字符串中,咱們能夠將其當作一個漏斗,當字符串中的每一個字符經過它時,都查找是否在這個類裏面,如若在,就匹配成功,不然out。以下:
/* match爲字符串的方法,它的惟一參數就是一個正則表達式, 若是該正則表達式設置了標誌g,該方法返回的數組包含的就是出如今字符串中的全部匹配。 詳細的用法將在下面「正則表達式在String中的應用」細講 */ "abc".match(/[abc]/g);
匹配結果爲:
若是咱們的意願是,想匹配除字符a、b、c以外的字符呢?咱們能夠定義一個否認類,只需將^符號放入[ ]中做爲開頭就OK啦。以下:
"abc".match(/[^abc]/g);
因爲某些字符類常常用到,固JavaScript的正則表達式就用反斜槓(\)與一些特殊字符組合起來表示這些經常使用類,而沒必要再須要咱們自行添加,如\d。
經常使用正則字符類以下:
字符類 |
匹配 |
例子 |
[ …] |
位於方括號之中的任意字符 |
/M[onke]y/ 匹配 "Moy" |
[ ^…] |
除包含在方括號之中的任意字符 |
/M[^onke]y/ 匹配 "May" |
. |
除換行符以外的任意字符 |
/../ 匹配 "Mo" |
\w |
字母、數字或下劃線 |
/1\w/ 匹配 "1A" |
\W |
除字母、數字和下劃線以外的字符 |
/1\W/ 匹配 "1%" |
\s |
單個空白字符 |
/M\sK/ 匹配 "M K" |
\S |
單個非空白字符 |
/M\SK/ 匹配 "M_K" |
\d |
0到9的數字 |
/\d/ 匹配 "1" |
\D |
非數字 |
/\D/ 匹配 "M" |
--重複匹配--
當咱們須要匹配三位數字時,咱們能夠這樣:/\d\d\d/,可是當咱們須要匹配10位或者更多時呢?考慮到這一點,正則表達式爲咱們提供了重複字符{ n, m },表示匹配前一項至少n次,可是不能超過m次。例如,剛纔咱們所說的匹配三位數字時,咱們能夠利用重複字符這樣啦:/\d{3}/。
因爲某些重複類型常常用到,so,正則規定一些特殊字符表示這些重複類型。
正則重複字符,詳情見下:
字符 |
含義 |
例子 |
{n, m} |
匹配前一項至少n次,但不能超過m次 |
/\d{2,3}/ 匹配"12" |
{n, } |
匹配前一項至少n次,或者更多 |
/\d{2, }/ 匹配"123" |
{n} |
匹配前一項剛好n次 |
/\d{2}/ 匹配"12" |
? |
匹配前一項0次或者1次,等價於{0,1} |
/\d?/ 匹配"2" |
+ |
匹配前一項1次或者屢次,等價於{1, } |
/\d+/ 匹配"12" |
* |
匹配前一項0次或者屢次,等價於{0, } |
/\d*/ 匹配"12" |
另,以上重複字符重複規則爲:儘量多的匹配,即俗稱的「貪婪匹配」,如:"aaaa".match(/a+/);匹配的就是整個字符串"aaaa",而不是匹配到第一個字符a時,就放棄匹配。
那麼,有所謂的"貪婪匹配",就有"非貪婪匹配",它的規則嘛,確定與"貪婪匹配"相反咯,即:儘量少的匹配。
那麼,怎麼才能觸發非貪婪模式呢?
只須要在重複字符後加入?,就ok啦,如({1, 4}?、+?等),如"aaaa".match(/a+?/);就只會匹配首個字符a咯。
注意,是儘量少的匹配,而不是少的匹配哦。
神馬意思?以下:
"aaab".match(/a*b/);
"aaab".match(/a*?b/);
!匹配結果都是"aaab"!
有沒有點詫異,爲何"aaab".match(/a*?b/);的匹配結果會是"aaab",而不是"ab"呢?
那是由於正則匹配都是從左往右的,就"aaab".match(/a*?b/);而言,當遇到首字符a時,它會繼續往下匹配,直到能符合匹配模式/a*?b/爲止,這就是爲何說是儘量少的匹配,前提是知足匹配規則。
如"abbb".match(/ab*?/)的匹配結果就是"a"啦。
--字符 |、( )、(?: …)--
1.一、字符" | " 用於分隔,表示或。
什麼意思?
舉個栗子,如/ab | cd | ef/就能夠匹配字符串"ab"或者"cd"或者"ef"。
是否是和字符類[ ]很像啊?
是的,如/a | b | c/和/[abc]/匹配效果是同樣的哦。
But,字符類[ ]僅針對單個字符而言,而分隔字符" | "涉及更廣,能夠針對多個字符而言,如上述所說的/ab | cd | ef/,字符類就不行咯。
你可能會說,若是我想對利用" | "組裝的類進行屢次匹配呢?
加個括號就是啦。如:
/(ab | cd |ef)+/
好滴,說到括號,咱們再來看看它的做用。很是強大哦。
1.二、括號"( )"
括號的做用以下:
一、咱們能夠將一個單獨的項目組合成一個子表達式,以便咱們能夠用|、*等來處理它。如,上訴所示的/(ab | cd | ef)+/。
二、利用括號括起來的部分,咱們能夠在正則表達式的後面引用前面用括號括起來的子表達式的匹配結果,注意是結果,而不是括起來的正則表達式。
針對第二點,有什麼用呢?如咱們有個需求,我想匹配在單引號或者雙引號中的數字(’12345’)時,咱們就可垂手可得利用這第二點,寫好正則表達式,以下:
/(['"])\d*\1/
測試結果以下:
好了,就第二點做用而言,結合上述demo,咱們再來看看它的具體引用法則吧:
----以反斜槓\加數字的方式,引用前面帶括號的子表達式,而這個數字呢指的就是第幾個子表達式,計算規則爲從左往右,計算遇到的左括號" ( ",到想引用的地方位置爲止,不管在括號中還嵌套不嵌套括號。
測試Demo以下:
咦,假若我只想讓括號的做用爲分組,而不想在後面計入引用呢?畢竟括號多了,很差計算呢。
那麼,咱們就來看看字符(?: …)咯。
1.三、(?: …)
(?: …)的做用就是,規定括號只用於分組,而不計入後面的引用,很差理解,看個demo就明白啦。以下:
/(Java(?:Script))(nice)/
若是我想在末尾引用子表達式nice,那麼是\2,而不是\3咯,由於用(?: …)來分組滴,只管分組,而不引用,切記切記。
對(?: …)的測試demo以下:
--匹配位置--
在前面咱們提到,建立正則對象時,可選字符m表示:多行模式,^和$錨除了匹配字符串的開頭和結尾外,還匹配每行的開頭和結尾。
那麼這個^和$就是正則爲咱們提供的匹配位置,即所謂的錨。
例如:
將/JavaScript/變爲/^JavaScript/,就只匹配字符串中開頭爲JavaScript的啦,如匹配"JavaScriptxxx"中的JavaScript,而不匹配"xxxJavaScript"中的JavaScript。
正則表達式中的錨字符詳情見下:
字符 |
含義 |
^ |
匹配字符串的開頭 |
$ |
匹配字符串的結尾 |
\b |
匹配一個詞語的邊界,指[a-zA-Z_0-9]以外的字符 |
\B |
匹配非詞語邊界位置 |
(? = p) |
正前向聲明,exp1(?=exp2),匹配後面是exp2的exp1 |
(? ! p) |
反前向聲明,exp1(?!exp2),匹配後面不是exp2的exp1 |
^和$好理解,可是\b、(?=)、(?!)可能比較陌生,結合上表,咱們再來看看下面的demo就好啦。
對於\b的Demo以下:
對於(? = p)的Demo以下:
對於(? ! p)的Demo以下:
哎,本想一鼓作氣,沒想到寫完基礎篇發現已經這麼晚了。。。有時間再梳理下正則表達式在JavaScript中的應用吧。
具體應用,見"理清JavaScript正則表達式--下篇"
晚安,everyone~