JavaScript正則表達式入門 ===================== 常常用戶在一個網頁里登錄註冊帳號時,要輸入用戶名、手機號、郵箱地址、設置密碼等項目。而對於用戶輸入的用戶名是否規範,輸入的是否是郵箱地址、密碼強度如何等等都可以通過一 正則表達式 制定相應的規則來驗證校檢,來實現一個非常 ...
JavaScript正則表達式入門
常常用戶在一個網頁里登錄註冊帳號時,要輸入用戶名、手機號、郵箱地址、設置密碼等項目。而對於用戶輸入的用戶名是否規範,輸入的是否是郵箱地址、密碼強度如何等等都可以通過一正則表達式制定相應的規則來驗證校檢,來實現一個非常複雜的業務邏輯。
在編寫處理字元串的程式或網頁時,經常有查找符合某些特定規則的字元串的需要。正則表達式就是用於描述這些規則的工具。正則表達式英文全稱為(Regular Expression),
- 正則表達式可以做什麼,總之需要抽取某字元串特定的數據和欄位,都應用到了正則表達式。
- 前端數據的校檢
- 大數據,採集爬取
創建正則表達式
使用正則表達式字面量
// 語法: /pattern/flag const reg = /at/g; // g可選,代表全局模式,匹配所有含有"at"的字元串
使用RegExp對象構造函數,可以實現正則表達模式隨時改變,適用於必須在運行時動態生成正則表達式的情形,如用戶輸入
// 語法: new RegExp(pattern [, flags]) let regex = new RegExp('ab+c', 'g'); let regex = new RegExp(/.at/gi); // str為用戶要查詢的值,trim()用於去除字元串的前置和後置空格 let str = document.getElementById('u-input').value.trim(); let re = new RegExp(str, 'g');
正則表達式語法
正則表達式必須寫在一行中,因為它們不支持註釋和空白
一個用來匹配URL的正則表達式如下:
var parseUrl = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var url = "http://www.ora.com:80/goodparts?q#fragment";
var result = parseUrl.exec(url);
// exec()方法成功匹配字元串的話,則返回一個字元串片段組成的數組
正則表達式對應的結構圖(右鍵新標簽看大圖)
- 正則表達式被包圍在一對斜杠
//
中,表示開始符和結束符。 - 容器:() [] {}
()
一對括弧為一個捕獲組[]
作為一個字元集合,匹配方括弧中的任意字元。{}
尾碼裡面的數字決定這個因數應該被匹配的次數,(/){0,3} 表示/會被匹配0次,或者1~3次。
- 捕獲組與非捕獲型組
- 捕獲型組 格式:
(. . .)
會複製它所匹配的文本,放到result數組裡。 - 非捕獲型組 格式:
(?: . . .)
只是匹配文本,不保存到result數組裡。如果不需要使用匹配後的文本,通常用非捕獲型來替代少量不優美的捕獲型分組,因為捕獲會有性能上的損失。
- 捕獲型組 格式:
- /^... $/
^
和$
分別置於模式的最前和最後,表示匹配字元串的開始和結束,保證開頭和結尾沒有多餘的內容。
^
在不同位置表示不同的意思。- 字元類[^?#]以^開始,表示這個類包含除?#外的所有字元。
- 位於整個模式字元類的開頭,則表示此字元串的開始,只匹配那些從開頭就像該字元串(URL)一樣的字元串。
?
位於首碼和尾碼- 尾碼,如
-?
表示這個負號是可選的,(...)?
表示這個分組是可選的
- 尾碼,如
+
和*
- 尾碼
+
表示匹配一個或多個,相當{1,}。 - 尾碼
*
表示匹配0個或多個,相當{0,}。
- 尾碼
更多特殊字元用法,見MDN正則表達式中的特殊字元
元字元
像上面闡釋那些具有特殊功能的字元
/ [ ] () { } ? + * | . ^ $
普通字元
除了元字元外,其他均是普通字元可以直接按字面處理使用,當然如果要使用元字元以及一些控制字元如 -
(範圍像是A-Z,加上轉義可以當作負號來用) ,可以通過在其前面加上轉義\
符號來去除它自身的特殊用途,即使其字面化。值得註意的是,\
不能首碼不能使字母或數字字面化。
正則表達式筋骨脈絡圖
主體結構
分支
序列
因數
轉義
字元集
字元轉義
分組
量詞
兩個重要方法test()和exec()
regexp.exec(string)
exec()方法在一個指定字元串中搜索匹配,找到返回一個數組,並更新正則表達式兌現的屬性。返回的數組完全匹配成功的文本作為第一項,將正則括弧里匹配成功的作為數組填充到後面。匹配失敗則返回Null。如果只是為了判斷是否匹配,則可以使用RexExp.test()或者String.search()。
var matches = /hello \S+/.exec('This is a hello world!');
console.log(matches[0]); // 'hello world!'
當rexExp帶有g
標誌(全局搜索所有匹配的字元串)時,可以多次執行exec()查找所有匹配,即一個匹配模式在同一個字元串中發生了幾次。
regexp.test(string)
test()執行一個檢索,如果regexp與string,則返回true,否則返回false。
可用於if條件語句中
function testinput(re, str) {
if(re.test(str)) {
// 要執行的語句
} else {
// 要執行的語句
}
}
一些例子
因為正則表達式是有關字元串的複雜規則的,所以字元串String的匹配、替換、查找等方法都可以傳入正則表達式作為參數,處理正則表達式的方法有regexp.exec、regexp.test、string.match、string.replace、string.search和string.split。
把String對象分割成字元串數組
需求:利用正則表達式分割用戶輸入的字元,允許一次批量輸入多個內容,格式可以為數字、中文、英文等,可以通過用回車,逗號(全形半形均可),頓號,空格(全形半形、Tab等均可)等符號作為不同內容的間隔
// 指定的分隔符
var re = /[-,,、.\s]+/g;
// 也可以使用Unicode編碼表示 re = /[\u002c\uff0c\u3001\s]+/g;
// 可以聲明一個空的數組容器
var data = [];
法一:RegExp.protype[@@split]()方法
// 語法:str.split([separator[,limit]]) // str為用戶輸入的值 data = data.concat(str.split(re));
法二:String.protype.split()
// 語法:regexp[Symbo.split](str[,limit]) data = data.concat(re[Symbol.split](str));
兩個方法的使用方法相同,只是this和參數順序不同。
使用正則表達式匹配實現輸入查詢
已知存在一個數組data,現在用戶輸入一個值來查詢是否存在某個字元串,匹配到且做一定標識(如顏色的改變)
法一:使用正則表達式
reg.test()
方法,找到返回true,否則為false。data.forEach(function (element, index, array) { // str為用戶要查詢的值 var re = new RegExp(str, 'g'); // 匹配到的內容則改變背景顏色,沒有匹配到的則為預設顏色 if (re.test(element.innerHTML)) { element.style.background = '#49b310'; element.style.border = '1px solid #ccc'; } else { element.style.background = '#ff3f41'; } });
法二:使用字元串位置方法
indexOf()
或lastIndexOf()
方法,找到返回字串首次出現的下標,找不到則返回-1。if (data[index].indexOf(str) !== -1) { // 設置標識}
正則表達式之空格處理
(更多見維基百科:全形和半形)
中文/英文輸入法下,按space鍵分別出全形空格和半形空格。使用轉義字元\s
可以匹配任何空白符,它等同於[\f\n\r\t\u000B\u0020\u00A0\u2028\u2029]
,這是Unicode空白的一個不完全子集。
- 一些額外的情況處理
總結
不要複製粘貼,杜絕死記硬背,誠心正意,自證良知,由外入里,層層剖析。
更詳細的回答見知乎:你是如何學會正則表達式的?
線上工具
拓展閱讀
- 20分鐘學會一門實用“技術”,互聯網人裝逼炫技必備
- 《JavaScript語言精粹》:有關正則表達式說的很詳細,精辟。