正則表達式
最近在做面試准備的時候,突然發現自己對正則還不夠熟悉,特寫此文,鞏固知識,查漏補缺,也給對這個知識點不夠熟悉的朋友簡單回顧一下。
什么是正則表達式?
使用單個字符串來描述、匹配一系列符合某個句法規則的字符串搜索模式。
當你在文本中搜索數據時,你可以用搜索模式來描述你要查詢的內容。
正則表達式可以是一個簡單的字符,或一個更復雜的模式。
正則表達式可用於所有文本搜索和文本替換的操作。
創建正則表達式
- 使用正則表達式字面量,由包含在斜杠
/
之間的模式組成,如下所示:
/* 使用字面量方法 */
const regex1 = /xy+z/;
const regex2 = /^[a-zA-Z]+[0-9]*\W?_$/gi;
在加載JavaScript引擎之后,正則表達式字面量提供正則表達式的編譯。當正則表達式保持不變時,使用此方法可獲得更好的性能。
- 調用
RegExp
對象的構造函數,如下所示:
/* 使用構造函數方法 */
let regex1 = new RegExp("xy+z");
let regex2 = new RegExp("^[a-zA-Z]+[0-9]*\\W?_$", "gi");
使用構造函數創造正則對象時,需要常規的字符轉義規則(在前面加反斜杠 \
),一般使用在匹配模式未知,需要在運行時使用字符串創建。
正則表達式的模式
一個正則表達式是由簡單字符和特殊字符組合而成的,例如/abc/
代表匹配包含有子字符串abc
的字符串,當你需要搜索一個包含更多條件的匹配時,例如搜尋一個或者多個字符,或者搜尋空格,那么這個時候就需要使用特殊字符,例如,模式/ab*c/
代表匹配由一個單獨的a
,大於等於0個b
,一個單獨的c的字符串組合。在字符串'cbbadfabbbc'
中,這個模式匹配了子字符串'abbbc'
。
正則表達式中使用的特殊字符的完整列表和使用規則詳見mdn
字符 | 描述 |
---|---|
\ | 轉義字符 |
^ | 起始字符 |
$ | 結束字符 |
* | 匹配前一個字符(表達式)0或多次 |
+ | 匹配前一個字符(表達式)1或多次 |
? | 匹配前一個字符(表達式)0或一次 |
. | 匹配除換行符之外的任何單個字符(表達式) |
(x) | 匹配字符‘x’,並且記住匹配項,括號被稱為 捕獲括號 |
(?:x) | 匹配‘x’,但是不記住匹配項。這種叫做非捕獲括號。 |
x(?=y) | 匹配'x'僅僅當‘x’后面跟着'y',這種叫做正向肯定查找。 |
x(?!y) | 匹配'x'僅僅當‘x’后面不跟着‘y’,這個叫做正向否定查找。 |
x|y | 匹配‘x’或者‘y‘ |
{n} | n是一個正整數,匹配了前面一個字符剛好發生了n次。 |
{n,m} | n和m都是整數,匹配前面的字符至少n次,最多m次。 |
[xyz] | 一個字符集合。匹配方括號中的任意字符,包括轉義序列。 |
[^xyz] | 一個反向字符集。它匹配任何沒有在方括號中的字符。 |
[\b] | 匹配一個退格(U+0008)。 |
\b | 匹配一個詞的邊界。 |
\B | 匹配一個非單詞邊界。 |
\cX | 當X是處於A到Z之間的字符的時候,匹配字符串的一個控制符。 |
\d | 匹配一個數字。 |
\D | 匹配一個非數字字符。 |
\f | 匹配一個換頁符。 |
\n | 匹配一個換行符。 |
\r | 匹配一個回車符。 |
\s | 匹配一個空白字符,包括空格,制表符,換頁符,換行符。 |
\S | 匹配一個非空白字符。 |
\t | 匹配一個水平制表符。 |
\v | 匹配一個垂直制表符。 |
\w | 匹配一個單字字符。 |
\W | 匹配一個非單字字符。 |
\1 | 在正則表達式中,它返回最后的第n個字捕獲的字符串 |
\0 | 匹配NULL字符,不要在這后面跟其他小數 |
\u{hhhh} | 使用Unicode值hhhh匹配字符(十六進制數字) |
使用正則表達式的方法
-
ReExp對象的
exec
和test
的方法方法 描述 exec
一個在字符串中執行查找匹配的RegExp方法,它返回一個數組(未匹配到則返回null)。 test
一個在字符串中測試是否匹配的RegExp方法,它返回true或false。 -
String對象的
match
、replace
、search
、和split
方法方法 描述 match
一個在字符串中執行查找匹配的String方法,它返回一個數組或者在未匹配到時返回null。 search
一個在字符串中測試匹配的String方法,它返回匹配到的位置索引,或者在失敗時返回-1。 replace
一個在字符串中執行查找匹配的String方法,並且使用替換字符串替換掉匹配到的子字符串。 split
一個使用正則表達式或者一個固定字符串分隔一個字符串,並將分隔后的子字符串存儲到數組中的String方法 你可以使用test或search方法來驗證在一個字符串中的正則匹配是否被找到;或者使用exec或match方法獲取返回數組。如果你使用exec或match方法並且匹配成功了,那么這些方法將返回一個數組並且更新相關的正則表達式對象的屬性和預定義的正則表達式對象(詳見下)。如果匹配失敗,那么exec方法返回null(也就是false)。
在接下來的例子中,腳本將使用exec方法在一個字符串中查找一個匹配。
var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
如果你不需要訪問正則表達式的屬性,這個腳本通過另一個方法來創建myArray:
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
如果你想通過一個字符串構建正則表達式,那么這個腳本還有另一種方法:
var myRe = new RegExp("d(b+)d", "g");
var myArray = myRe.exec("cdbbdbsbzd");
console.log(myArray);
// ["dbbd", "bb", index: 1, input: "cdbbdbsbz", groups: undefined]
通過這些腳本,匹配成功后將返回一個數組並且更新正則表達式的屬性,如下表所示。
對象 | 屬性或索引 | 描述 | 在例子中對應的值 |
---|---|---|---|
myArray |
匹配到的字符串和所有被記住的子字符串。 | ["dbbd", "bb"] |
|
index |
在輸入的字符串中匹配到的以0開始的索引值。 | 1 |
|
input |
初始字符串。 | "cdbbdbsbz" |
|
[0] |
匹配到的所有字符串(並不是匹配后記住的字符串)。注:原文"The last matched characters.",應該是原版錯誤。匹配到的最終字符。 | "dbbd" |
|
myRe |
lastIndex |
下一個匹配的索引值。 | 5 |
source |
模式文本。在正則表達式創建時更新,不執行。 | "d(b+)d" |
在這個例子中如第二種形式所示,你可以使用一個正則表達式創建一個沒
匹配成功之后,正則表達式的返回屬性可以進行訪問,因此如果你需要訪問一個正則表達式的屬性,你應該首先把它賦值給一個變量 。
使用帶括號的子字符串匹配
在一個正則表達式內使用括號,可以存儲括號內的子匹配。回調這些括號里的子匹配可以使用數組元素[index]。
下面的實例使用replace()
方法來轉換字符串中的單詞,在匹配完成之后的替換環節使用替代的$1
,$2
表示第一個和第二個匹配的子字符串。
var re = /(\w+)\s(\w+)/;
var str = "Mike Json";
var newstr = str.replace(re,"$1,$2");
console.log(newstr);
//輸出"Mike,Json";
正則表達式修飾符
修飾符 | 描述 |
---|---|
i | 不區分大小寫匹配。 |
g | 執行全局匹配(查找所有匹配而非在找到第一個匹配后停止)。 |
m | 執行多行匹配。 |
y | 執行“粘性”搜索,匹配從目標字符串的當前位置開始,可以使用y標志。 |
包含修飾符的正則表達式:
/* flages代表修飾符*/
var regexp = /pattern/flages;
var regexp = new RegExp("pattren","flages");
例如,re = /\w+\s/g
將創建一個查找一個或者多個字符后帶有空格的正則表達式
var re = /\w+\s/g;
var str = "fee fi fo fum";
var myArray = str.match(re);
console.log(myArray);
這段代碼將輸出["fee","fi","foo"]。
實例
用字符串字符驗證輸入
在下面這個例子中,我們期望用戶輸入一個電話號碼,當用戶點擊“驗證”按鈕后,我們的腳本開始檢查這些數字是否正確。如果輸入正確(匹配正則表達式所固定的字符序列),腳本顯示一條感謝用戶的信息並確認該數字。如果這串數字不合法,腳本提示用戶電話號碼不正確。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">
var re = /(?:\d{3}|\(\d{3}\))([-\/\.])*\d{8}/;
function testInfo(phoneInput) {
var OK = re.exec(phoneInput.value);
if (!OK)
window.alert(phoneInput.value + '電話號碼格式不正確');
else
window.alert('謝謝,你的電話號碼是' + OK[0]);
}
</script>
</head>
<body>
<p>請輸入你的電話號碼,並點擊確認按鈕。<br>
電話號碼格式例如: ###-########.
</p>
<form action="#">
<input id="phone"></input>
<button onclick="testInfo(document.getElementById('phone'));">
Check
</button>
</form>
</body>
</html>