JS正則表達式

定義

  正則表達式能夠理解成匹配符合要求的字符串的表達式,由普通字符和特殊字符構成,用來查找替換文本java

建立

字面量(直接量)

  在一對反斜線中寫正則表達式內容,如/js/node

  通常多使用字面量方式,但字面量把正則「寫死了」,不能改變正則表達式

構造函數

  構造正則表達式的實例,如new RexExp('js')數組

  內部傳入的參數爲字符串/字符串的變量框架

  若是須要根據用戶輸入來改變正則表達式,則用構造函數的方法建立ide

 

字符分類

普通字符

  字母、數字、下劃線、漢字、沒有特殊含義的符號(,;!@等)函數

  實際上不是特殊字符的字符都是普通字符測試

特殊字符

  \:將特殊字符轉義成普通字符url

模式修飾符

  i:ignoreCase,匹配時忽視大小寫spa

  m:multiline,多行匹配

  g:global,全局匹配

  字面量建立正則時,模式修飾符寫在一對反斜線後

1 var find = /js/i;

   構造對象建立正則時,模式修飾符做爲第二個參數,傳遞給RexExp對象

1 var find = new RegExp('js','i');

 

字符匹配方式

字符類

  用[]括起來,會將待匹配字符從最開頭到最後挨個找,看是否有字符類中的字符,若是有,返回這個字符,不然返回null

  用^表示取反,即除了字符類中的字符,其他字符只要出現就返回這個字符

  用-表示範圍,即只要字符出如今字符類的範圍裏,就返回該字符

  表示範圍時,範圍的字符的ASCII碼必須小於等於範圍後面字符,且不可跨越大小寫、數字範圍,不一樣範圍之間緊密相連便可

  

 經常使用字符類

  .:可取到除了換行符(\n)之外的全部字符

  \w:包含大小寫字符、數字以及下劃線

  \W:包含除了大小寫字符、數字以及下劃線以外的字符(即\w取反

  \d:包含0-9的數字

  \D:包含除了0-9數字以外的字符(即\d取反

  \s:包含空格、製表符、unicode裏的多個空格符

  \S:除了空格、製表符、unicode裏多個空格符以外的字符(即\s取反

  以上經常使用字符類無需寫到[]裏,但也均可以寫到[]中,寫入多個時,只能匹配其中一類(例如\d\s只能按目標字符串順序,匹配數字或空格)

重複

  用添加在{}內的數字並放在字符類後,用以控制匹配字符類的次數

  其中的數字能夠寫兩個,逗號分隔(注意逗號和數字之間不要有空格),前面的數表示下限,後面的表示上限

  下限必須小於等於上限,下限不可省略,上限可省略

  

數量的簡寫

  ?:表示匹配0/1次

  +:表示至少匹配1次

  *:表示可匹配0次及以上

  

 非貪婪匹配

  正則表達式默認貪婪匹配,例如用+規定能夠匹配一個以上的字符,正則會儘量多地去匹配而不是取下限匹配一次

  在量詞({}或簡寫符號)後加?,就會在條件容許下儘量少去匹配

  (用課裏說到的一個案例,說明只是儘量去不貪婪) 

選擇

  用|,表示匹配時選擇其中之一便可,匹配到其中一個就輸出

  實際匹配時,會按照字符串中的書寫順序,從左往右找,跟正則中的選項從左向右查找,若是匹配上其中一個,就輸出

  

分組

  用()把字符類括起來,用來對整個字符類進行數量的修飾等操做,同時匹配時也會返回分組中字符類的查找結果

  當不須要返回分組中的內容時(不捕獲分組中的內容),在分組的內容前加上?:便可

  

  多個括號嵌套時,從左到右以左半括號的位置,分別爲第一個、第二個、第三個分組

  

引用

  對用()括起來的字符類,能夠在正則表達式中用\序號的形式直接引用,其中序號表示該分組號(便是第幾個分組

  引用時,該分組必須設置爲捕獲(即分組前不可有?:),不然返回null

  

  引用讓後面匹配到和前面同樣的內容(例如忽略大小寫時保持先後匹配的大小寫一致,匹配到同一個標籤等)

  

 

位置匹配方式

首匹配

  讓要匹配的正則中的字符必須在原字符串中的開頭

  在正則表達式最開始加^(此處的^同字符類中的不一樣,字符類中表示取反

尾匹配

  讓要匹配的正則中的字符必須在原字符串中的結尾

  在正則表達式最後加$

單詞邊界匹配

  用\b來實現(\b表示\w和\W之間的位置,即單詞的開頭和以前的部分的位置、單詞的結尾和結尾後的部分之間的位置)

前瞻性匹配/負向前瞻性匹配

  用來匹配字符串後爲/不爲指定字符串內容的字符串(例如匹配上java後爲/不爲script的)

  前瞻性匹配須要在匹配的內容前加上?=,負向前瞻性則加上?!

  

應用

  能夠驗證輸入內容都是數字(例如用在QQ號全是數字的密碼等)

1 var find = /^\d+$/;//此處表示首尾之間所有是數字,且數字至少爲1個
首位匹配

  也可查找指定的class名稱(即便class先後有多個空格)

 1 function getByClassName(className,parentNode){
 2     //若是有getElementsByClassName方法,直接調用
 3     if(!document.getElementByClassName){
 4         return document.getElementsByClassName(className);
 5     }
 6     else{
 7         //當沒有傳入parentNode時,自動賦值爲document
 8         parentNode = parentNode || document;
 9         var nodeList = [];
10         //挑選出parentNode下的全部標籤
11         var allNodes = parentNode.getElementsByTagName('*');
12         //此處用正則表示匹配上classname先後有多個空格以及在首尾的狀況
13         var pattern = new RegExp('(^|\\s+)'+className+'($|\\s+)');
14         //用循環遍歷,找出其中能夠用正則匹配出的指定class名稱的標籤
15         //將這些標籤裝到nodeList數組中
16         for(var i=0;i<allNodes.length;i++){
17             if(pattern.test(allNodes[i].className)){
18                 nodeList.push(allNodes[i]);
19             }
20         }
21         //完成裝入,返回nodeList數組
22         return nodeList;
23     }
24 }
class查找(首尾匹配)
 1 function getByClassName(className,parentNode){
 2     //若是有getElementsByClassName方法,直接調用
 3     if(!document.getElementByClassName){
 4         return document.getElementsByClassName(className);
 5     }
 6     else{
 7         //當沒有傳入parentNode時,自動賦值爲document
 8         parentNode = parentNode || document;
 9         var nodeList = [];
10         //挑選出parentNode下的全部標籤
11         var allNodes = parentNode.getElementsByTagName('*');
12         //此處用正則表示匹配上classname爲一個單獨單詞的狀況
13         var pattern = new RegExp('\\b'+className+'\\b');
14         //用循環遍歷,找出其中能夠用正則匹配出的指定class名稱的標籤
15         //將這些標籤裝到nodeList數組中
16         for(var i=0;i<allNodes.length;i++){
17             if(pattern.test(allNodes[i].className)){
18                 nodeList.push(allNodes[i]);
19             }
20         }
21         //完成裝入,返回nodeList數組
22         return nodeList;
23     }
24 }
class查找(單詞邊界)

 

正則實例方法

test

  用來測試待檢測的字符串中是否有能夠匹配到正則表達式的字符串

  若是有返回true,不然返回false

  

exec

  可用來匹配字符串中符合正則表達式的字符串

  若是匹配到,返回該字符串的數組(注意這個字符串自己是不帶有引號的,也就是你讓它匹配的文字內容),不然返回null

  沒寫全局匹配時,只會匹配原字符串中第一個符合正則要求的字符串

  添加分組時,返回符合正則表達式的內容以及分組內容,開啓全局匹配不改變該結果

  

  返回的數組中有如下屬性:

  第一個屬性(0)爲匹配上的字符串

  index爲該字符串第一個字母的起始位置

  input爲被匹配數組的所有內容

  

 

toString/toLocaleString

  把正則表達式的內容轉化成字面量形式字符串/有本地特點的字符串(JS中沒效果

valueOf

  返回正則表達式自己

  

正則實例屬性

lastIndex

  當沒設置全局匹配時,該屬性值始終爲0

  設置了全局匹配時,每執行一次exec/test來匹配,latIndex就會移向匹配到的字符串的下一個位置,當指向的位置後沒有能夠再次匹配的字符串時,下一次執行exec返回null,test執行返回false,而後lastIndex歸零,從字符串的開頭從新匹配一輪

  能夠理解成,每次正則查找的起點就是lastIndex

  

ignoreCase、global、multiline

  判斷正則表達式中是否有忽略大小寫、全局匹配、多行匹配三個模式修飾符

  

$1-9

  返回正則中的分組(最多用9個分組),但必須先執行exec或test方法

  

source

  返回字面量形式的正則表達式(相似於toString

  

flags

  返回正則表達式的模式匹配符

input($_)

  返回正則查找的原字符串,但若是沒有執行過exec或test方法,則返回undefined

lastmatch($&)(不經常使用)

  返回最近一次匹配到的字符

left(right)Context($`或$')(不經常使用)

  返回上次匹配左/右剩餘的字符

lastParen(不經常使用)

  返回上次經過分組捕獲的子選項

 

String對象中和正則相關的方法

search

  查找字符串中是否有匹配正則的字符串,有則返回字符串第一次出現時的位置,無則返回null

  正則中不管是否有全局匹配都不會影響返回結果

  

match

  匹配字符串中符合正則表達式的字符串,並返回該字符串的一個數組,其中包括字符串內容位置

  若是正則設置全局匹配,則一次性返回全部符合正則表達式的字符串數組

  若是其中添加了分組,返回符合要求的字符串以及分組的一個數組,但若是同時開啓全局匹配則不會在數組中添加分組內容

  

  match中的正則添加了多行匹配,只有在同時添加全局匹配以及首位匹配時才起做用(例如匹配全局中每行行首的指定字符)

  只添加多行匹配時同普通匹配一致,只添加多行匹配和全局匹配也和全局匹配模式一致

  

split

  分隔字符串時,傳入的參數能夠是字符串(,等),也能夠是正則表達式

  

replace

  替換字符串時,參數能夠傳遞字符串,也可爲正則表達式

  能夠在過濾敏感詞時使用(見下方案例)

1 var str = '我草草地去吃了一頓草草的飯';
2 var find = /草/g;//設置全局匹配以屏蔽全部敏感詞
3 console.log(str.replace(find,function($0){
4     var result = '';
5     for(var i=0;i<$0.length;i++){//獲取其中敏感詞的長度,添加不一樣數量的*
6         result += '*';
7     }
8     return result;
9 }));
replace過濾敏感詞

 

經常使用的正則表達式

  在寫正則時,須要先明確規則,而後按照規則逐條編寫

  建議能夠把經常使用的正則用一個對象來包括起來,用屬性名錶示匹配啥,屬性值表示正則

QQ號

  全是數字,首位不可爲0,最少5位數(目前最大11位數,能夠爲了將來考慮不設置上限)

1 //此處首位匹配,首位不是0,且都是數字,很多於5位
2 var findQQ = /^[1-9]\d{4,}$/;
QQ號的正則

暱稱(以慕課網爲例)

  2-18位,中英文、數字及下劃線

1 //爲了匹配暱稱,添加首尾匹配
2 var findname = /^[\u4e00-\u9fa5a-zA-Z0-9_{2,18}]$/;
3 //能夠把英文、數字、下劃線統一用\w表示
4 var findname2 = /^[\u4e00-\u9fa5\w]{2,18}$/;
暱稱的正則

密碼(以慕課網爲例)

  6-16位,不可用空格(空白字符),區分大小寫

1 //\s表示空白字符(包括空格、製表符、換行等),\S則取反
2 var findpassword = /^\S[6,16}$/;
3 // 也可用窮舉
4 var findpassword2 = /^[\w~#!@$%\[\]]{6,16}$/;
密碼的正則

去除字符串首尾的空白字符

  正則也跟函數相似,沒必要追求用一個正則表示所有的功能,能夠考慮用多個正則以加強可讀性

  這裏也能夠考慮用函數來封裝正則表達式,實現去除空白的效果

1 //能夠同時首尾替換,設置全局匹配
2 var deletespace = /^\s+|\s+$/g;
去除空白1
1 //也可用兩個正則,一個用來匹配前面的空格,一個用來匹配後面的
2 var pattern1 = /^\s+/;
3 var pattern2 = /\s+$/;
4 console.log(str.replace(pattern1,'').replace(pattern2,''));
去除空白2

轉駝峯

  把連字符後的字母變成大寫

1 //全局匹配全部連字符,而後找到其後面的字母,在函數中返回其大寫形式
2 //考慮到要返回該字母,須要對字母進行一個分組
3 var pattern = /-([a-z])/gi;
4 console.log(str.replace(pattern,function(all,letter){
5     return letter.toUpperCase();
6 }));
轉駝峯

匹配HTML標籤

  只是匹配HTML標籤,包括開始和閉合標籤,標籤中的屬性名和屬性值

1 //先順向思考,匹配標籤名(可能有反斜槓),再匹配其中屬性名和屬性值
2 var tocamel = /<\/?[a-zA-Z]+(\s+[a-zA-Z]+=".*")*>/g;
HTML標籤1
1 //反向思考,一個標籤中不可能有>,所以排除便可
2 var findHTML = /<[^>]+>/g;
HTML標籤2

email郵箱

  @前能夠是一個相似用戶名的結構(字母數字下劃線),也可包括.com,@後是一個至少有一個.的結構

  對於這些複雜的結構,能夠先分組,即搭建正則的框架,而後再去書寫詳細內容

1 //先搭建框架,而後最後看哪些分組不是必須的就去掉
2 var findemail = /(\w+\.)*(\w+)@(\w+\.)+([a-z])/i;
3 //拆除沒必要要的框架後以下
4 var findemail2 = /(?:\w+\.)*\w+@(?:\w+\.)+[a-z]/i;
郵箱1
1 //改變分組模式,能夠理解成@先後都是一堆字母數字後加.組成的,@後的最後是字母結尾
2 var findemail3 = /^([a-z0-9]+)([_-.][a-z0-9]+)*@([a-z0-9]+)([_-.][a-z0-9]+)*\.([a-z]{2,4})$/i;
3 //拆去不須要的分組,並把不須要捕獲的添加不捕獲
4 var findemail4 = /^[a-z0-9]+(?:[_-.][a-z0-9]+)*@[a-z0-9]+(?:[_-.][a-z0-9]+)*\.[a-z]{2,4}$/i;
郵箱2

URL地址

  由協議:\\(可省略)主機名(:端口號,通常省略)/路徑幾個部分組成

1 //先只考慮http和https這兩個協議
2 var findurl1 = /^(https?:\/\/)?([^:\/]+)(:\d+)?(\/.*)?$/;
URL1

  主機名其實是多個以.分隔開的字符串組成的,其中能夠有數字、字母、下劃線、連字符等,可是不能夠以連字符開頭/結尾

1 //只針對主機名來寫一個正則
2 var hostnamefind = /[a-z0-9]|[a-z0-9][-a-z0-9]*[a-z0-9]/i;
3 //讓主機名匹配詳細,最後的部分可用窮舉
4 var hostnamefind2 = /^([a-z0-9]\.|[a-z0-9][-a-z0-9]*[a-z0-9]\.)*(com|edu|gov|net|org|[a-z]{2}+)$/;
5 //不窮舉,可簡單把最後的com等用若干個英文字母代替
6 var hostnamefind3 = /^([a-z0-9]\.|[a-z0-9][-a-z0-9]*[a-z0-9]\.)*([a-z]+)$/
主機名
相關文章
相關標籤/搜索