@(javascript)[js正則表達式]javascript
[toc]html
正則表達式一直是一個使人頭疼但卻又是十分重要的一個東西。熟練的使用正則表達式可讓你的工做事半功倍。接下來,一塊兒來看看正則表達式是什麼吧!java
正則表達式,又稱規則表達式。(英語:Regular Expression,在代碼中常簡寫爲regex、regexp或RE),計算機科學的一個概念。正則表一般被用來檢索、替換那些符合某個模式(規則)的文本。正則表達式
var reg = / pattern / flags;
複製代碼
就像上面的,正則表達式是由兩個/
符號包裹起來的,兩個/
裏面的(上面的pattern)就是須要的任何簡單或者是複雜的正則表達式。而在第二個/
後面是一個或者是多個標誌(flags),用來標明正則表達式的行爲。 flags有如下五種行爲:數組
下面根據JavaScript正則表達式的速查表中的分類來對每一下進行一個說明。bash
基礎裏面呢主要有6
須要記憶的東西,分別是:函數
.
:匹配除了換行之外其餘全部字符a
:匹配字符a
,衍生爲匹配單個字母ab
:匹配字符串ab
,衍生爲匹配字符串a|b
:匹配a或者b
,就是或者的意思a*
:匹配一次或者是屢次a
\
:轉義符號,轉義一個特殊的字符// `.`的使用
var reg = /./g;
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (7) ["a", "b", "c", "d", "e", "f", "g"]
// `a`的使用
var reg = /A/gi; // 全局匹配。忽略大小寫
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (7) ["a"]
// `ab`的使用
var reg = /AbCdef/gi; // 全局匹配。忽略大小寫
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (7) ["abcdef"]
// `a|b`的使用 一
var reg = /a|b|c|d/; // 非全局匹配。
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // ["a", index: 0, input: "abcdefg"]
// `a|b`的使用 二
var reg = /a|b|c|d/g; // 全局匹配。
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (4) ["a", "b", "c", "d"]。使用全局匹配。會在匹配對後繼續匹配
// `a*`的使用
var reg = /a*/;
var text = "abcdcba";
var res = text.match(reg);
console.log(res); // ["a", index: 0, input: "abcdcba"]
// `a*`的使用
var reg = /a*/g; // 全局匹配。
var text = "abcdcba";
var res = text.match(reg);
console.log(res); // (8) ["a", "", "", "", "", "", "a", ""]。使用全局匹配會把以後沒有匹配到的轉化爲空字符串
// `\`的使用 回到第一個 . 的使用那裏。若是我把 . 前面加一個 \ 符號,那麼這個點就是一個普通的點了
var reg = /\./g; // 全局匹配。
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // null
複製代碼
JavaScript中須要使用 \
的特殊符號有:(
)
[
]
{
}
.
|
+
*
?
\
^
$
以及 空白
。測試
[ab-d]
:a,b,c,d四個字符中的一個,衍生爲使用[]
,那就是匹配其中的一個[^ab-d]
:除了a,b,c,d四個字符其餘的任意字符,衍生爲使用[^]
能夠排除[]裏面的東西[\b]
:退格字符,瞭解\d
:一個0-9的數字\D
:一個非數字\s
:一個空白字符\S
:一個非空白字符\w
:匹配一個字母,數字或者是下劃線\W
:匹配一個除字母,數字,下劃線以外的任意字符// `[a-z]`的使用
var reg = /[a-z]/g; // 全局匹配。匹配 a-z 的任意一個,由於是全局匹配。因此會一直找。可是不會有 1234
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (4) ["a", "b", "c", "d"]
// `[a-z]`的使用
var reg = /[^a-z]/g; // 全局匹配。匹配 除了 a-z 的任意一個。因此是 1 2 3 4。由於是全局匹配。因此會一直找
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (4) ["1", "2", "3", "4"]
// `[\b]`的使用
var reg = /[\b]/g; // 全局匹配。匹配 \b,固然也能夠匹配其餘的特殊轉義字符,見 正則表達式特殊字符
var text = "abcd\b1234";
var res = text.match(reg);
console.log(res); // (4) ["1", "2", "3", "4"]
// `\d`,`\D`,`\s`,`\S`,`\w`,`\W`的使用
var reg = /\D\d/g; // 全局匹配。匹配一個非數字與一個數字。二者緊靠在一塊兒 注意順序
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["d1"]
// 若是是下面的一個,則匹配 null
var reg = /\D\d/g; // 全局匹配。匹配一個數字與一個非數字。二者緊靠在一塊兒 注意順序
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // null
// 匹配一個
var reg = /\D\s\w\d/g; // 全局匹配。注意順序 注意大小寫
var text1 = "abcd1234";
var text2 = "abcd _1234";
var res1 = text1.match(reg);
var res2 = text2.match(reg);
console.log(res1); // null
console.log(res2); // ["d _1"]
複製代碼
*
:匹配0次
或者屢次
。等價於{0,}
+
:匹配一次
或者屢次
。等價於{1,}
?
:匹配0次
或者一次
。等價於{0,1}
{2}
:只匹配2
次{2, 5}
:匹配2-5
次{2,}
:匹配2次
或者屢次
這裏涉及到一個貪婪匹配
與非貪婪匹配
。 貪婪匹配
指的是使用以上量詞的時候會按照最大次數進行匹配。 非貪婪匹配
則是按最小次數進行匹配。ui
使用非貪婪匹配只需在兩次後面加上一個?
spa
// `*`的使用
// 非全局匹配。
var reg = /[a-z]*/; // 匹配 a-z 的0個或者多個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd", index: 0, input: "abcd1234"]
// 全局匹配。
var reg = /[a-z]*/g; // 匹配 a-z 的0個或者多個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (6) ["abcd", "", "", "", "", ""]。當匹配爲 0 個的時候,會變成空字符串。對比 + 號
// `+`的使用
// 非全局匹配。
var reg = /[a-z]+/; // 匹配 a-z 的0個或者多個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd", index: 0, input: "abcd1234"]
// 全局匹配。
var reg = /[a-z]+/g; // 匹配 a-z 的0個或者多
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd"]。由於至少匹配一個,因此不會有空字符串。對比 * 號
// `?`的使用
// 非全局匹配。
var reg = /[a-z]?/; // 匹配 a-z 的0個或者一個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["a", index: 0, input: "abcd1234"]。匹配到一個就停下來
// 全局匹配。
var reg = /[a-z]?/g; // 匹配 a-z 的0個或者一個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["a", "b", "c", "d", "", "", "", "", ""]。abcd匹配到了。1234則是空字符串。
複製代碼
以上說的都屬於貪婪匹配
。都是按最多個匹配的。若是是非貪婪匹配
。則是按照最少的次數匹配。
// `*`的使用
// 非全局匹配。貪婪匹配
var reg = /[a-z]*/; // 匹配 a-z 的0個或者多個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd", index: 0, input: "abcd1234"]
// 全局匹配。貪婪匹配
var reg = /[a-z]*/g; // 匹配 a-z 的0個或者多個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (6) ["abcd", "", "", "", "", ""]。當匹配爲 0 個的時候,會變成空字符串。對比 + 號
// 非全局匹配。非貪婪匹配
var reg = /[a-z]*?/; // 匹配 a-z 的0個或者多個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["", index: 0, input: "abcd1234"]
// 全局匹配。非貪婪匹配
var reg = /[a-z]*?/g; // 匹配 a-z 的0個或者多個
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (9) ["", "", "", "", "", "", "", "", ""]
複製代碼
以上就是貪婪匹配
與非貪婪匹配
的區別。不過不論是如何。在匹配是0
次的時候。空字符串的個數
老是匹配不成功部分的字符串的長度+1
(...)
:捕獲組(?...)
:非捕獲組\Y
:匹配第Y個被捕獲的組(也稱反向引用
)。其中Y
是一個數字,這個數組取值範圍是*
,即{0,}
。可是建議反向引用
不要索引大於9的捕獲性分組。var reg = /ab(cd(1234))/;
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (3) ["abcd1234", "cd1234", "1234", index: 0, input: "abcd1234"]
複製代碼
分析:
()
外面的字符以後在匹配 ()
裏面的。結果中的 "abcd1234""cd1234"
與"1234"
var reg = /ab(?:cd(1234))/;
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (3) ["abcd1234", "1234", index: 0, input: "abcd1234"]
複製代碼
分析:非捕獲組就是不捕獲,就行上面的結果中沒有了"cd1234"
那麼捕獲與非捕獲有什麼區別呢? 記得看寵物小精靈的時候小智看見新的小精靈扔球抓小精靈的時候就屬於一個捕獲,若是看見不扔球那就是不捕獲。那捕獲和不捕獲有什麼區別呢?就行抓小精靈同樣,抓住了以後就能夠用了嘛!因此被捕獲的東西以後是可使用的。那麼怎麼使用呢? 問得好。這時候就須要使用到\Y
了。
var reg1 = /(a)/;
var reg2 = /(a)\1/; // 至關因而 /(a)a/
var text1 = "aabb1234";
var text2 = "aabb1234";
var res1 = text1.match(reg1);
var res2 = text2.match(reg2);
console.log(res1); // ["a", "a", index: 0, input: "aabb1234"]
console.log(res2); // ["aa", "a", index: 0, input: "aabb1234"]
複製代碼
上面的例子中,reg1
與 reg2
僅僅有一點不一樣。可是匹配後的東西是不一樣的。簡單地說,就是,使用 \Y
後會賦值第Y個捕獲的組。如下代碼說明經過$Y
來接收相應的捕獲組。不能從0開始
\Y
var reg = /ab(cd(1234))/;
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (3) ["abcd1234", "cd1234", "1234", index: 0, input: "abcd1234"]
console.log(RegExp.$0); // undefined
console.log(RegExp.$1); // cd1234
console.log(RegExp.$2); // 1234
var res1 = text.replace(reg,"$1$2"); // 使用 $1 $2 取出捕獲組的內容
console.log(res1); // cd12341234
複製代碼
^
:字符串的開始必須是$
:字符串的結尾必須是\b
:匹配文字(單詞)邊界\B
:非文字(單詞)邊界(?=...)
:積極的前瞻(也叫前瞻或者是順序確定環視)(?!...)
:消極的前瞻(也加後瞻或者是順序否認環視)^
,$
的使用var reg = /^b.*\d$/; // 要求字符 b 開頭,中間 * 個任意字符(除換行符),必須以數字結束
var text1 = "abcd1234";
var text2 = "bcd";
var text3 = "bcd1234";
var res1 = text1.match(reg);
var res2 = text2.match(reg);
var res3 = text3.match(reg);
console.log(res1); // null
console.log(res2); // null
console.log(res3); // ["bcd1234", index: 0, input: "bcd1234"]
複製代碼
\b
,\B
的使用var reg = /\bhi\b/; //
var text1 = "hi";
var text2 = "him";
var text3 = "history";
var res1 = text1.match(reg);
var res2 = text2.match(reg);
var res3 = text3.match(reg);
console.log(res1); // ["hi", index: 0, input: "hi"]
console.log(res2); // null
console.log(res3); // null
複製代碼
var reg = /abcd(?=1234)/;
var text = "abcd1234";
var text1 = "abcdefg";
var res = text.match(reg);
var res1 = text1.match(reg);
console.log(res) // ["abcd", index: 0, input: "abcd1234"]
console.log(res1) // null
複製代碼
看上面的例子能夠看出積極的前瞻匹配1234
前面的abcd
,不匹配def
前面的abcd
;而消極的前瞻偏偏相反,看下面的例子。
var reg = /abcd(?!=1234)/;
var text = "abcd1234";
var text1 = "abcdefg";
var res = text.match(reg);
var res1 = text1.match(reg);
console.log(res) // null
console.log(res1) // ["abcd", index: 0, input: "abcd1234"]
複製代碼
\n
:換行符\r
:回車符\t
:製表符\0
:空字符\YYY
:8進制字符\xYY
:十六進制字符\uYYYY
:十六進制字符\cY
:控制符 正則的特殊字符在實際中運用的比較少,具體的用法與以前講到的[\b]
相似。上面的兩個十六進制字符
中,\xYY
主要匹配數字字母等。而\uYYYY
則是爲了匹配漢字以及如下特殊的符號。正則表達式替換主要是替換一些字符。主要如下幾個,但是在replace
中使用。
$$
:插入$
$&
:插入整個匹配$'
:插入匹配項後面的字符串$Y
:插入第Y個捕獲的組var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var res = text.match(reg);
console.log(res); // (2) ["淡如水,", ",", index: 4, input: "君子之交淡如水,小人之交甘若醴"]
複製代碼
$$
:插入$
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$$");
console.log(newStr); // 君子之交$小人之交甘若醴
複製代碼
$&
:插入整個匹配var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$&");
console.log(newStr); // 君子之交淡如水,小人之交甘若醴
複製代碼
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$`");
console.log(newStr); // 君子之交君子之交小人之交甘若醴
複製代碼
$'
:插入匹配項後面的字符串var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$'");
console.log(newStr); // 君子之交小人之交甘若醴小人之交甘若醴
複製代碼
$Y
:插入第Y個捕獲的組var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$1");
console.log(newStr); // 君子之交,小人之交甘若醴
複製代碼
此方法專門爲捕獲組設計的。此方法接收一個參數,及須要測試的字符串
。返回數組或者是null。但返回的值包含兩個額外的屬性: index
:匹配性在字符串中的位置 input
:應用正則的表達式
var reg = /你(我他(與她))/
var text = "你我他與她";
var res = reg.exec(text);
console.log(res); //(3) ["你我他與她", "我他與她", "與她", index: 0, input: "你我他與她"]
複製代碼
["你我他與她", "我他與她", "與她", index: 0, input: "你我他與她"]
的結果。使用res[下標]
能夠查看具體的匹配下。從第二項開始纔是捕獲項
。使用res.index
與res.input
查看起始位置與匹配的字符串。
exec()方法始終返回一項,若是設置了全局匹配g
,只會從上一次結束的敵法繼續查找,而不會返回多項。
var text = "bat, cat, fat";
var reg1 = /.at/;
var res = reg1.exec(text);
console.log(res.index); // 0
console.log(res[0]); // bat
var res = reg1.exec(text);
console.log(res.index); // 0
console.log(res[0]); // bat
var reg2 = /.at/g;
var res = reg2.exec(text);
console.log(res.index); // 0
console.log(res[0]); // bat
var res = reg2.exec(text);
console.log(res.index); // 5
console.log(res[0]); // cat
複製代碼
接收一個字符串做爲參數,返回: true
:匹配 false
:不匹配
var text = "abcd1234";
var reg1 = /\D/g;
var reg2 = /\s/g;
var res1 = reg1.test(text);
console.log(res1); // true
var res2 = reg2.test(text);
console.log(res2); // false
複製代碼
語法:var reg = new RegExp(參數1[,參數2])
;
var reg = new RegExp("\D","gi");
var text = "ABd1234";
var res = reg.exec(text);
console.log(res); // ["d", index: 2, input: "ABd1234"]
複製代碼
看上面的例子。兩個參數須要使用字符串
。 可是,上面的例子有一個問題。沒有按照咱們所想的出現一個A
,而是一個d
。同時,咱們忽略大小寫在看一下:
var reg = new RegExp("\D","g");
var text = "ABd1234";
var res = reg.exec(text);
console.log(res); // null
複製代碼
因此,使用構造函數還有一個須要注意的就是全部的元字符都須要雙重轉義
。將上面的代碼換爲下面的看看
var reg = new RegExp("\\D","g");
var text = "ABd1234";
var res = reg.exec(text);
console.log(res); // ["A", index: 0, input: "ABd1234"]
複製代碼
注意上面的\\D
。這個才表示一個元字符。剛剛的就是一個\
一個D
。因此。在正則的構造函數中使用元字符
須要雙重轉義
。
電話號碼匹配:/^1[3-8]\d{9}$/
電子郵件:/[a-zA-z0-9_-]{6,12}@[a-zA-z0-9_-]+\.[a-zA-z0-9]+/
匹配特定了的郵件:/[a-zA-z0-9_-]{6,12}@(163|qq|gmail)\.com/
更多的匹配可查閱:最全的經常使用正則表達式大全
以上就是關於正則的一些使用概念以及使用方法。若是想要熟練的使用正則去匹配或者是修改字符串。仍是須要不斷的練習纔是。