JavaScript 正則表達式上——基本語法


定義

JavaScript種正則表達式有兩種定義方式,定義一個匹配類似 <%XXX%> 的字符串

1. 構造函數

var reg=new RegExp('<%[^%>]+%>','g');

2. 字面量

var reg=/<%[^%>]%>/g;
  • g: global,全文搜索,默認搜索到第一個結果接停止
  • i: ingore case,忽略大小寫,默認大小寫敏感
  • m: multiple lines,多行搜索(更改^ 和$的含義,使它們分別在任意一行對待行首和行尾匹配,而不僅僅在整個字符串的開頭和結尾匹配)

元字符

正則表達式讓人望而卻步以一個重要原因就是其轉義字符太多了,組合非常之多,但是正則表達式的元字符在正則表達式中具有特殊意義的專用字符,可以用來規定其前導字符)並不多

元字符:( [ { \ ^ $ | ) ? * + .

並不是每個元字符都有其特定意義,在不同的組合中元字符有不同的意義,分類看一下

預定義特殊字符

字符 含義
\t 水平制表符
\r 回車符
\n 換行符
\f 換頁符
\cX 與X對應的控制字符(Ctrl+X)
\v 垂直制表符
\0 空字符

 

 

 

 

 

 

 

字符類

一般情況下正則表達式一個字符(轉義字符算一個)對應字符串一個字符,表達式 ab\t 的含義是

但是我們可以使用元字符[]來構建一個簡單的類,所謂類是指,符合某些特征的對象,是一個泛指,而不是特指某個字符了,我們可以使用表達式 [abc] 把字符a或b或c歸為一類,表達式可以匹配這類的字符

元字符[]組合可以創建一個類,我們還可以使用元字符^創建反向類/負向類,反向類的意思是不屬於XXX類的內容,表達式 [^abc] 表示不是字符a或b或c的內容

范圍類

按照上面的說明要是我們希望匹配單個數字那么表達式是這樣的

[0123456789]

如果是字母那么。。。,好麻煩,正則表達式還提供了范圍類,我們可以使用 x-y來連接兩個字符表示從x到y的任意字符,這是個閉區間,也就是說包含x和ybenshen,這樣匹配小寫字母就很簡單了

[a-z]

要是想匹配所有字母呢?在[]組成的類內部是可以連寫的,我們還可以這樣寫 [a-zA-Z]

預定義類

剛才使用正則我們創建了幾個類,來表示數字,字母等,但這樣寫也很是麻煩,正則表達式為我們提供了幾個常用的預定義類來匹配常見的字符

字符 等價類 含義
. [^\n\r] 除了回車符和換行符之外的所有字符
\d [0-9] 數字字符
\D [^0-9] 非數字字符
\s [ \t\n\x0B\f\r] 空白符
\S [^ \t\n\x0B\f\r] 非空白符
\w [a-zA-Z_0-9] 單詞字符(字母、數字、下划線)
\W [^a-zA-Z_0-9] 非單詞字符

 

 

 

 

 

 

 

 

有了這些預定義類,寫一些正則就很方便了,比如我們希望匹配一個 ab+數字+任意字符 的字符串,就可以這樣寫了 ab\d.

 

邊界

正則表達式還提供了幾個常用的邊界匹配字符

字符

含義

^

以xx開頭

$

以xx結尾

\b

單詞邊界,指[a-zA-Z_0-9]之外的字符

\B

非單詞邊界

 

 

 

 

 

 

 

 

看個不負責任的郵箱正則匹配(切勿模仿,小括號后面會講到) \w+@\w+\.(com)$

量詞

之前我們介紹的方法都是一一匹配的,如果我們希望匹配一個連續出現20次數字的字符串難道我們需要寫成這樣

\d\d\d\d...

為此正則表達式引入了一些量詞

字符 含義
? 出現零次或一次(最多出現一次)
+ 出現一次或多次(至少出現一次)
* 出現零次或多次(任意次)
{n} 出現n次
{n,m} 出現n到m次
{n,} 至少出現n次
   

 

 

 

 

 

 

 

 

看幾個使用量詞的例子

\w+\b Byron 匹配 單詞+邊界+Byron

 

(/\w+\b Byron/).test('Hi Byron'); //true

(/\w+\b Byron/).test('Welcome Byron'); //true

(/\w+\b Byron/).test('HiByron'); //false

 \d+\.\d{1,3} 匹配三位小數的數字

 貪婪模式與非貪婪模式

看了上面介紹的量詞,也許愛思考的同學會想到關於匹配原則的一些問題,比如{3,5}這個量詞,要是在句子種出現了十次,那么他是每次匹配三個還是五個,反正3、4、5都滿足3~5的條件,量詞在默認下是盡可能多的匹配的,也就是大家常說的貪婪模式

'123456789'.match(/\d{3,5}/g); //["12345", "6789"] 

 既然有貪婪模式,那么肯定會有非貪婪模式,讓正則表達式盡可能少的匹配,也就是說一旦成功匹配不不再繼續嘗試,做法很簡單,在量詞后加上 ? 即可

'123456789'.match(/\d{3,5}?/g); //["123", "456", "789"]

 分組

有時候我們希望使用量詞的時候匹配多個字符,而不是像上面例子只是匹配一個,比如希望匹配Byron出現20次的字符串,我們如果寫成 Byron{20} 的話匹配的是Byro+n出現20次,怎么把Byron作為一個整體呢?使用()就可以達到次目的,我們稱為分組

(Byron){20}

 

 如果希望匹配Byron或Casper出現20次該怎么辦呢?可以使用字符 | 達到或的功效

(Byron|Casper){20}

 

 我們看到圖中有個#1的東東,那是什么?使用分組的正則表達式會把匹配項也放到分組中,默認就是按數字編號分發的,各異根據編號獲得捕獲的分組內容,這個在一些希望具體操作第幾個匹配項的函數中很有用

(Byron).(ok)

 

如果有分組嵌套的情況,外面的組的編號靠前

((^|%>)[^\t]*)

 

有時候我們不希望捕獲某些分組,只需要在分組內加上 ?: 就可以了,着並不意味着該分組內容不屬於正則表達式,只是不會給這個分組加編號了而已

(?:Byron).(ok)

 

 其實在C#等語言中分組還可以起名字,不過JavaScript不支持

前瞻

表達式 含義
exp1(?=exp2) 匹配后面是exp2的exp1
exp1(?!exp2) 匹配后面不是exp2的exp1

 

 

 

 

說的有些抽象,看個例子 good(?=Byron)

(/good(?=Byron)/).exec('goodByron123'); //['good']
(/good(?=Byron)/).exec('goodCasper123'); //null
(/bad(?=Byron)/).exec('goodCasper123');//null

通過上面例子可以看出 exp1(?=exp2) 表達式會匹配exp1表達式,但只有其后面內容是exp2的時候才會匹配,也就是兩個條件,exp1(?!exp2) 比較類似

good(?!Byron)

(/good(?!Byron)/).exec('goodByron123'); //null
(/good(?!Byron)/).exec('goodCasper123'); //['good']
(/bad(?!Byron)/).exec('goodCasper123');//null

參考 

司徒正美 JavaScript正則表達式

Regexper

PS:博客中的圖都是用第二個鏈接做的,幫助人圖形化理解正則表達式,真心不錯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM