一、字符匹配攻略
- 橫向模糊匹配(貪婪模式)
- 縱向模糊匹配 [ ]
- 字符組 [ ] : 匹配一個字符
- 范圍表示法:比如 [123456abcdefGHIJKLM]霜浴,可以寫成 [1-6a-fG-M]够庙。用連字符 - 來省略和簡寫
- 排除字符組 :例如 [^abc]恭应,表示是一個除 "a"、"b"耘眨、"c"之外的任意一個字 符昼榛。字符組的第一位放 ^(脫字符),表示求反的概念剔难。
- 常見的簡寫形式
字符組 | 具體含義 |
---|---|
\d????????? | 表示 [0-9]胆屿。表示是一位數(shù)字。 記憶方式:其英文是 digit(數(shù)字)钥飞。 |
\D | 表示 [^0-9]莺掠。表示除數(shù)字外的任意字符衫嵌。本 |
\w | 表示 [0-9a-zA-Z_]读宙。表示數(shù)字、大小寫字母和下劃線楔绞。 記憶方式:w 是 word 的簡寫结闸,也稱單詞字符唇兑。 |
\W | 表示 [^0-9a-zA-Z_]。非單詞字符桦锄。 |
\s | 表示 [ \t\v\n\r\f]安岂。表示空白符克滴,包括空格、水平制表符、垂直制表符市殷、換行符、回車符底靠、換頁符囚灼。記憶方式:s 是 space 的首字母,空白符的單詞是 white space |
\S | 表示 [^ \t\v\n\r\f]黑毅。 非空白符嚼摩。 |
. | 表示 [^\n\r\u2028\u2029]。通配符矿瘦,表示幾乎任意字符枕面。換行符、回車符缚去、行分隔符和段分隔符 除外潮秘。記憶方式:想想省略號 ... 中的每個點(diǎn),都可以理解成占位符病游,表示任何類似的東西唇跨。 |
- 常見的量詞簡寫模式
量詞 | 具體含義 |
---|---|
{m,} ?? | 表示至少出現(xiàn) m 次。 |
{m} | 等價于 {m,m}衬衬,表示出現(xiàn) m 次买猖。 |
? | 等價于 {0,1},表示出現(xiàn)或者不出現(xiàn)滋尉。 記憶方式:問號的意思表示玉控,有嗎? |
+ | 等價于 {1,},表示出現(xiàn)至少一次狮惜。 記憶方式:加號是追加的意思高诺,得先有一個,然后才考慮追加碾篡。 |
* | 等價于 {0,}虱而,表示出現(xiàn)任意次,有可能不出現(xiàn)开泽。 記憶方式:看看天上的星星牡拇,可能一顆沒有,可能零散有幾顆,可能數(shù)也數(shù)不過來惠呼。 |
- 貪婪匹配與惰性匹配
通過在量詞后面加個問號就能實(shí)現(xiàn)惰性匹配
惰性量詞 | 貪婪量詞 |
---|---|
{m,n}? | {m,n} |
{m,}? | {m,} |
?? | ? |
+? | + |
*? | * |
TIP : 對惰性匹配的記憶方式是:量詞后面加個問號导俘,問一問你知足了嗎,你很貪婪嗎?
多選分支 : (p1|p2|p3)剔蹋,其中 p1旅薄、p2 和 p3 是子模式,用 |(管道符)分隔泣崩,表示其中任何之一
案列分析
// 匹配時間
var regex = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/;
console.log( regex.test("23:59") );
console.log( regex.test("02:07") );
console.log( regex.test("7:9") );
// => true
// => true
// => true
// 匹配id
var regex = /id=".*?"/ // 一定要加惰性匹配少梁,不然就是貪婪匹配,結(jié)果會錯誤的
var string = '<div id="container" class="main"></div>'; console.log(string.match(regex)[0]);
// => id="container"
或者如下
// 匹配id
var regex = /id="[^"]*"/ // 先匹配id=" 然后匹配任何不是"的任意個字符 最后再匹配"
var string = '<div id="container" class="main"></div>'; console.log(string.match(regex)[0]);
// => id="container"
二矫付、位置匹配攻略
- 關(guān)于位置的6個錨
錨 | 含義 |
---|---|
^ | (脫字符)匹配開頭猎莲,在多行匹配中匹配行開頭 |
$ | (美元符號)匹配結(jié)尾,在多行匹配中匹配行結(jié)尾 |
\b | 單詞邊界技即,具體就是 \w 與 \W 之間的位置著洼,也包括 \w 與 ^ 之間的位置,和 \w 與 $ 之間的位置 |
\B | \b 的反面的意思而叼,非單詞邊界 |
(?=p) | 正向斷言(預(yù)查) ;檢查某個字符后面的字符是否滿足某個規(guī)則身笤,該規(guī)則不成為匹配結(jié)果,并且不成為捕獲組 |
(?!p) | 負(fù)向斷言(預(yù)查); 檢查某個字符后面的字符是否不滿足某個規(guī)則葵陵,該規(guī)則不成為匹配結(jié)果液荸,并且不成為捕獲組 |
- 案列分析
// 數(shù)字的千位分隔符表示法
var regex = /(?!^)(?=(\d{3})+$)/g;
var result = "12345678".replace(regex, ',') console.log(result);
// => "12,345,678"
result = "123456789".replace(regex, ','); console.log(result);
// => "123,456,789"
三、正則表達(dá)式括號的作用
- 分組:
var regex = /(ab)+/g;
其中括號是提供分組功能脱篙,使量詞 + 作用于 "ab" 這個整體 - 分支結(jié)構(gòu): 而在多選分支結(jié)構(gòu) (p1|p2) 中娇钱,此處括號的作用也是不言而喻的,提供了分支表達(dá)式的所有可能
- 提取數(shù)據(jù):可以從數(shù)組中獲取绊困,也可以從構(gòu)造函數(shù)餓全局屬性
9來獲取
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
console.log( string.match(regex) );
// => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"]
match
返回的一個數(shù)組文搂,第一個元素是整體匹配結(jié)果,然后是各個分組(括號里)匹配的 NOTE 內(nèi)容秤朗,然后是匹配下標(biāo)煤蹭,最后是輸入的文本
另外也可以使用正則實(shí)例對象的 exec 方法
- 替換
// 比如,想把 yyyy-mm-dd 格式取视,替換成 mm/dd/yyyy
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1"); console.log(result);
// => "06/12/2017"
- 反向引用 :
\捕獲組編號
// 寫一個正則支持匹配如下三種格式
// 2016-06-12
// 2016/06/12
// 2016.06.12
var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/; var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // true
console.log( regex.test(string4) ); // false
- 分組后面有量詞: 分組后面有量詞的話硝皂,分組最終捕獲到的數(shù)據(jù)是最后一次的匹配
// 分組 (\d) 捕獲的數(shù)據(jù)是 "5"
var regex = /(\d)+/;
var string = "12345";
console.log( string.match(regex) );
// => ["12345", "5", index: 0, input: "12345"]
var regex = /(\d)+ \1/;
console.log( regex.test("12345 1") ); // => false
console.log( regex.test("12345 5") ); // => true
- 非捕獲符號:
(?:)
只想要括號最原始的功能, 不會成為捕獲組 - 案例分析
// 字符串 trim 方法模擬
function trim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
console.log( trim(" foobar ") ); // => "foobar"
// 字符串 trim 方法模擬
function trim (str) {
return str.replace(/^\s*(.*?)\s*$/g, "$1");
}
console.log( trim(" foobar ") );
// => "foobar"
// 這里使用了惰性匹配 *?,不然也會匹配最后一個空格之前的所有空格的
// 非捕獲組
// 將每個單詞的首字母轉(zhuǎn)換為大寫
function titleize (str) {
return str.toLowerCase().replace(/(?:^|\s)\w/g, function (c) {
return c.toUpperCase(); });
}
console.log( titleize('my name is epeli') );
// => "My Name Is Epeli"
四作谭、回溯法
簡單總結(jié)就是稽物,正因?yàn)橛卸喾N可能,所以要一個一個試折欠。直到贝或,要么到某一步時秧倾,整體匹配成功了;要么最后都試完后,發(fā)現(xiàn)整體匹配不成功傀缩。
貪婪量詞“試”的策略是:買衣服砍價。價錢太高了农猬,便宜點(diǎn)赡艰,不行,再便宜點(diǎn)斤葱。
惰性量詞“試”的策略是:賣東西加價慷垮。給少了,再多給點(diǎn)行不揍堕,還有點(diǎn)少啊料身,再給點(diǎn)。
分支結(jié)構(gòu)“試”的策略是:貨比三家衩茸。這家不行芹血,換一家吧,還不行楞慈,再換幔烛。
五、正則表達(dá)式的拆分
結(jié)構(gòu) | 說明 |
---|---|
字面量????????? | 匹配一個具體字符囊蓝,包括不用轉(zhuǎn)義的和需要轉(zhuǎn)義的饿悬。比如 a 匹配字符 "a", 又比如 \n 匹配換行符聚霜,又比如 . 匹配小數(shù)點(diǎn)狡恬。 |
字符組 | 匹配一個字符,可以是多種可能之一蝎宇,比如 [0-9]弟劲,表示匹配一個數(shù)字。也有 \d 的簡寫形式姥芥。 另外還有反義字符組函卒,表示可以是除了特定字符之外任何一個字符,比如 [^0-9]撇眯, 表示一個非數(shù)字字符报嵌,也有 \D 的簡寫形式。 |
量詞???? | 表示一個字符連續(xù)出現(xiàn)熊榛,比如 a{1,3} 表示 "a" 字符連續(xù)出現(xiàn)1到 3 次锚国。 另外還有常見的簡寫形式,比如 a+ 表示 "a" 字符連續(xù)出現(xiàn)至少一次玄坦。 |
錨 | 匹配一個位置血筑,而不是字符绘沉。比如 ^ 匹配字符串的開頭,又比如 \b 匹配單詞邊界豺总, 又比如 (?=\d) 表示數(shù)字前面的位置车伞。 |
分組 | 用括號表示一個整體,比如 (ab)+喻喳,表示 "ab" 兩個字符連續(xù)出現(xiàn)多次另玖, 也可以使用非捕獲分組 (?:ab)+。 |
分支 | 多個子表達(dá)式多選一表伦,比如 abc|bcd谦去,表達(dá)式匹配 "abc" 或者 "bcd" 字符子串。 反向引用蹦哼,比如 \2鳄哭,表示引用第 2 個分組。 |
- 操作符
操作符描述 | 操作符 | 優(yōu)先級 |
---|---|---|
轉(zhuǎn)義符 | \ | 1 |
括號和方括號 | (...)纲熏、(?:...)妆丘、(?=...)、(?!...)局劲、[...] | 2 |
量詞限定符 | {m}飘痛、{m,n}、{m,}容握、?宣脉、*、+ | 3 |
位置和序列 | ^剔氏、$塑猖、\元字符、一般字符 | 4 |
管道符(豎杠) | | | 5 |
- 所有結(jié)構(gòu)里谈跛,用到的元字符總結(jié)如下:
^羊苟、$、.感憾、*蜡励、+、?阻桅、|凉倚、\、/嫂沉、(稽寒、)、[趟章、]杏糙、{慎王、}、=宏侍、!赖淤、:、- ,
六谅河、replace 是很強(qiáng)大的
總體來說 replace 有兩種使用形式咱旱,這是因?yàn)樗牡诙€參數(shù),可以是字符串旧蛾,也可以是函數(shù)。 當(dāng)?shù)诙€參數(shù)是字符串時蠕嫁,如下的字符有特殊的含義:
屬性 | 描述 |
---|---|
|
匹配第 1-99 個 分組里捕獲的文本 |
$& | 匹配到的子串文本 |
$` | 匹配到的子串的左邊文本 |
$' | 匹配到的子串的右邊文本 |
$$ | 美元符號 |
- 案例分析
// 把 "2,3,5"锨天,變成 "5=2+3"
var result = "2,3,5".replace(/(\d+),(\d+),(\d+)/, "$3=$1+$2");
console.log(result);
// => "5=2+3"
// 把 "2,3,5",變成 "222,333,555"
var result = "2,3,5".replace(/(\d+)/g, "$&$&$&");
console.log(result);
// => "222,333,555"
// 把 "2+3=5"剃毒,變成 "2+3=2+3=5=5"
var result = "2+3=5".replace(/=/, "$&$`$&$'$&");
console.log(result);
// => "2+3=2+3=5=5"