基本語法
regular expression是計(jì)算機(jī)科學(xué)中的一個(gè)概念。正則表達(dá)式使用單個(gè)字符串來描述匹配一系列符合某個(gè)句法規(guī)則的字符串络它。
創(chuàng)建
- 構(gòu)造函數(shù)
var reg = new RegExp('<%[^%>]+%>','g');
- 字面量
var reg = /<%[^%]%>/g;
g全文搜索,i忽略大小寫,m多行搜索
元字符
字符 | 含義 |
---|---|
\t | 水平制表符 |
\n | 換行符 |
\r | 回車符 |
\f | 換頁符 |
\cX | 與x對(duì)應(yīng)的控制字符(Ctrl + x) |
\v | 垂直制表符 |
\0 | 空字符 |
具有特殊意義的專用字符啥箭,用來規(guī)定其前導(dǎo)字符
( [ { \ ^ $ | ) ? * + .
不同組合中的元字符有不同的意義,舉例
字符 | 含義 |
---|---|
\t | 水平制表符 |
\n | 換行符 |
\r | 回車符 |
\f | 換頁符 |
\cX | 與x對(duì)應(yīng)的控制字符(Ctrl + x) |
\v | 垂直制表符 |
\0 | 空字符 |
字符類
可以使用[]來構(gòu)建一個(gè)簡(jiǎn)單的類
var reg = /[abc123]/;
創(chuàng)建一個(gè)單字符的類爹梁,代表這個(gè)字符可以是a,可以是b,可以是c右犹,可以是1,...可以是3。
取反
可以使用^來進(jìn)行取反姚垃,
var reg = /[^abc123]/;
代表著這個(gè)單字符可以是任何其他的單字符念链,除了a,b,c,1,2,3之外。
范圍類
如果要匹配單個(gè)字符积糯,讓單字符只能取數(shù)字的話掂墓,可以使用字符類
寫成:
var reg = /[0123456789]/;
這么寫比較麻煩,所以可以使用范圍類看成,我們可以使用x-y來連接兩個(gè)字符君编,表示從x到y(tǒng)的任意字符,是個(gè)閉區(qū)間川慌,意味著包含x和y本身吃嘿,這樣祠乃,我們要匹配單個(gè)數(shù)字就可以寫成:
var reg2 = /[0-9]/;
要匹配所以的單個(gè)字母,可以寫為
var reg3 = /[a-zA-Z]/;
預(yù)定義類
上面創(chuàng)建了一些類抚芦,用來表示數(shù)組足陨,字母等欲芹。但是這么寫也比較麻煩,正則表達(dá)式提供了幾個(gè)常見的預(yù)定義類來匹配常見的字符
字符 | 等價(jià)類 | 含義 |
---|---|---|
. | [^\r\n] | 除了回車符和換行符之外的所有字符 |
\d | [0-9] | 數(shù)字字符 |
\D | [^0-9] | 非數(shù)字字符 |
\s | [\t\n\x0B\f\r] | 空白符 |
\S | [^\t\n\x0B\f\r] | 非空白符 |
\w | [a-zA-Z_0-9] | 單詞字符嘱支,字母,數(shù)字下劃線 |
\W | [^a-zA-Z_0-9] | 非單詞字符 |
有了這些預(yù)定義類挣饥,寫一些正則就比較方便了除师,比如我們希望匹配一個(gè)ab+數(shù)字+任意字符的字符串,就可以寫作:
var reg = /ab\d./;
邊界
正則表達(dá)式還提供了幾個(gè)常用的邊界匹配字符
字符 | 含義 |
---|---|
^ | 以xxx開頭 |
$ | 以xxx結(jié)尾 |
\b | 單詞邊界 |
\B | 非單詞邊界 |
^如果不寫在[]內(nèi)的話亮靴,不代表取反馍盟,代表以xxx開頭,例如:var reg = /hello/;
代表以hello開頭茧吊,相應(yīng)的也有$表示為以xxx結(jié)尾,舉例說明:
var reg = /^h\dm/g;
var str = 'h3m h4m h2m';
console.log(str.match(reg));// ["h3m"] 只匹配了第一個(gè)h\dm贞岭,因?yàn)橛衈
var reg2 = /h\dm$/g; // $代表以xxx結(jié)尾
console.log(str.match(reg2));//["h2m"] / 只匹配了最后一個(gè)h\dm 因?yàn)橛?
var reg3 = /^h\dm$/g; //代表既以h\dm開頭,又以h\dm結(jié)尾的
console.log(str.match(reg3)); // null 匹配不到
//關(guān)于既有開頭又有結(jié)尾的例子 比如匹配手機(jī)號(hào) 以1開頭搓侄,以10個(gè)數(shù)字結(jié)尾
var phoneReg = /^1\d{10}$/; //\d{10}代表10個(gè)數(shù)字
var phoneStr = '13892229999';
console.log(phoneStr.match(phoneReg)); //"13892229999" 匹配不到返回null
單詞邊界
var str = 'hello worhellold hello';
var reg = /hello/g;
console.log(str.match(reg)); // ["hello", "hello", "hello"] 會(huì)將3個(gè)hello都匹配到瞄桨,但是如果想要只匹配單詞hello的話要使用\b
var reg2 = /\bhello/g;
console.log(str.match(reg2)); // ["hello", "hello"] 只匹配到了單詞hello
var str2 = 'hello wor-hello-ld hello'; // 寫成如此格式,也被識(shí)別為合法的單詞
console.log(str2.match(reg2)); // ["hello", "hello", "hello"] 這么寫也被識(shí)別為合法的讶踪,所以匹配到了3個(gè)hello單詞
量詞
之前寫的方法都是一一匹配的芯侥,但是如果希望匹配一個(gè)連續(xù)出現(xiàn)很多次的字符,例如數(shù)字的字符串乳讥,不需要寫成\d\d\d\d
,我們可以使用量詞
字符 | 含義 |
---|---|
? | 出現(xiàn)一次或者0次(最多出現(xiàn)一次) |
+ | 出現(xiàn)一次或者多次(最少出現(xiàn)一次) |
* | 出現(xiàn)0次或者多次(任意次) |
{n} | 出現(xiàn)n次 |
{n,m} | 出現(xiàn)n到m次 |
{n,} | 至少出現(xiàn)n次 |
{,m} | 最多出現(xiàn)m次 |
使用舉例:
var reg = /[a-z]\d?/g; // ?代表最多出現(xiàn)一次
console.log('a12345b678cde'.match(reg)); //["a1", "b6", "c", "d", "e"] 因?yàn)楹竺娴腬d? 有?存在柱查,即最多出現(xiàn)一次,所以后面的cde沒有數(shù)字也可以被匹配到
var reg2 = /[a-z]\d+/g;
console.log('a12345b678cde'.match(reg2));//["a12345", "b678"],+為最少出現(xiàn)一次云石,則a唉工,b后面的有多少都可以匹配到,cde后面沒有數(shù)字所以匹配不到
var reg3 = /[a-z]\d*/g;
console.log('a12345b678cde'.match(reg3));//["a12345", "b678", "c", "d", "e"] *代表可以有任意多次汹忠,包括0淋硝,所以都能匹配到
var reg4 = /[a-z]\d{4}/g; //匹配字母后面4個(gè)字符
console.log('a12345b678cde'.match(reg4));//["a1234"]
var reg5 = /[a-z]\d{1,3}/g; //匹配字母后面1-3個(gè)字符
console.log('a12345b678cde'.match(reg5)); // ["a123", "b678"] 1-3盡量多的去匹配,3個(gè)沒有就2個(gè)宽菜,逐漸減小谣膳,先匹配多的
貪婪模式 非貪婪模式
上面提到的{n,m},如果出現(xiàn)多次铅乡,只要是n-m中的值都滿足條件继谚,到底是按照n還是m來匹配。 量詞在默認(rèn)條件下是盡可能多的匹配的阵幸,即默認(rèn)貪婪模式
var reg = /\d{3,5}/g; '123456789'.match(reg); //{"12345","6789"}
與貪婪模式相對(duì)的犬庇,就有非貪婪模式僧界,即盡可能少的匹配,一旦成功匹配之后不再繼續(xù)嘗試臭挽,在后面加上?即可
var reg2 = /\d{3,5}?/g; '123456789'.match(reg); //{"12345","6789"}
分組
上面的量詞解決的是單個(gè)字符重復(fù)多次的問題捂襟,如果我們需要匹配重復(fù)的多個(gè)字符,比如匹配hello出現(xiàn)20次欢峰,如果寫成hello{20}意味著是hell+o出現(xiàn)20次葬荷,o自己重復(fù)20次,而不是整個(gè)hello重復(fù)20次纽帖。
我們可以使用分組()來解決這個(gè)問題宠漩,寫成:
/(hello){20}/g;
或
對(duì)于上面的情況,如果我們希望匹配hello或者world出現(xiàn)20次懊直,可以通過使用 | 進(jìn)行或操作
/(hello|world){20}/g;
前瞻
表達(dá)式 | 含義 |
---|---|
exp1(?=exp2) | 匹配后面是exp2的exp1 |
exp1(?!exp2) | 匹配后面不是exp2的exp1 |
舉例:good(?=Bayon)
匹配后面有Bayon的good
var reg = /good(?=Bayon)/;
reg.exec('goodBayon123'); // ['good']
reg.exec('goodCasper123'); // null
正則表達(dá)式的一些相關(guān)方法
RegExp.prototype.test(str)
檢測(cè)字符串參數(shù)中是否存在正則表達(dá)式模式扒吁,存在返回true不存在返回false
var reg = /hello/; //用來檢驗(yàn)字符串 匹配成功了返回true
console.log(reg.test('hello world')); //true
//具體應(yīng)用舉例,用來判斷是否為手機(jī)號(hào)
function isPhoneNumber (str) {
if (/^1\d{10}$/g.test(str)) { //匹配到手機(jī)號(hào)時(shí)返回true
console.log('是合法的手機(jī)號(hào)碼');
}
}
isPhoneNumber('13812345678');
RegExp.prototype.exec(str)
用于正則表達(dá)式模式在字符串中運(yùn)行查找室囊,如果exec()找到了匹配的文本雕崩,則返回一個(gè)結(jié)果數(shù)組,否則返回null
除了數(shù)組元素和length屬性之外融撞,exec()方法返回對(duì)象還包括兩個(gè)屬性盼铁。
- index 屬性聲明的是匹配文本的第一個(gè)字符的位置
- input屬性則存放的是被檢索的字符串string
舉例說明:
var str = 'hallo deejay,hbllo world,hcllo daisy'; //通過正則找到各個(gè)錯(cuò)誤的hello
var reg = /h[a-z]llo/g;
var result = reg.exec(str);
console.log(result);//["hallo", index: 0, input: "hallo deejay,hbllo world,hcllo daisy"]
result = reg.exec(str);
console.log(result);//["hbllo", index: 13, input: "hallo deejay,hbllo world,hcllo daisy"]
result = reg.exec(str);
console.log(result);//["hcllo", index: 25, input: "hallo deejay,hbllo world,hcllo daisy"]
String.prototype.search(reg)
search()方法用于檢索字符串中指定的子字符串,或檢索與正則表達(dá)式相匹配的子字符串尝偎。
search方法不執(zhí)行全局匹配饶火,它將忽略標(biāo)志g,同時(shí)也忽略正則表達(dá)式對(duì)象的lastIndex屬性致扯,總是返回字符串的第一個(gè)匹配的位置
String.prototype.match(reg)
match()方法將檢索字符串肤寝,以找到一個(gè)或者多個(gè)與regexp匹配的文本。regexp是否有全局g標(biāo)志會(huì)影響結(jié)果抖僵。
String.prototype.replace(reg,replaceStr)
關(guān)于string對(duì)象的replace方法醒陆,一般可以傳入兩個(gè)字符串,但是只能replace一次裆针,如果把第一個(gè)參數(shù)傳入regexp的話,就可以是replace變得靈活寺晌。
var str = 'hallo deejay,hbllo world,hcllo daisy'; //通過正則找到各個(gè)錯(cuò)誤的hello
var reg = /h[a-z]llo/g;
str = str.replace(reg,'hello'); // 傳入的第一個(gè)參數(shù)為regexp世吨,找到匹配的字符串替換成hello
- String.prototype.replace(reg,function)
當(dāng)replace方法的第二個(gè)參數(shù)為function的時(shí)候,這個(gè)function會(huì)在每次替換的時(shí)候調(diào)用呻征。
var str = 'hallo deejay,hbllo world,hcllo daisy'; //通過正則找到各個(gè)錯(cuò)誤的hello
var reg = /h[a-z]llo/g;
str = str.replace(reg,function (value) {
console.log(arguments);
return value[0].toUpperCase() + value.substring(1,value.length);
})
console.log(str); //Hallo deejay,Hbllo world,Hcllo daisy
String.prototype.split(reg)
經(jīng)常使用split方法把字符串分割為字符數(shù)組
'a,b,c,d'.split(","); // ["a","b","c","d"];
相應(yīng)的耘婚,也可以使用regexp進(jìn)行切割:
"a1b2c3".split(/\d/); // ["a","b","c","d"]