RegExp對象
字面量
var reg=/\bis\b/g;
定義變量reg
然后把正則表達(dá)式文本寫到兩個反斜杠之間,"\正則文本\"
。\b
代表單詞邊界,\bis\b
代表正則is單純后面再加個\b
是保證is
是一個完整的單詞,而不是兩個字符。
var reg=/\bis\b/;
"He is a boy .This is a dog.Where is she?".replace(reg,'IS');
//"He IS a boy .This is a dog.Where is she?"
發(fā)現(xiàn)就匹配了第一個單純is
。
我們使用g
,也就是代表全文搜索匹配。var reg=/\bis\b/g;
var reg=/\bis\b/g;
"He is a boy .This is a dog.Where is she?".replace(reg,'IS');
//"He IS a boy .This IS a dog.Where IS she?"
構(gòu)造函數(shù)
var reg=new RegExp("\\bis\\b","g");
使用new
操作符來調(diào)用構(gòu)造函數(shù),構(gòu)造函數(shù)接收兩個參數(shù),第一個字符串里面是正則表達(dá)式的文本,這里有些特殊的地方就是反斜線寫了兩次,是因?yàn)镴avascript中反斜線本身就是特殊字符,如果我們想使用的話,就要進(jìn)行轉(zhuǎn)義,然后第二個參數(shù)是字符串,也是標(biāo)志g
也就是代表全文搜索匹配
var reg=new RegExp("\\bis\\b","g");
"He is a boy .This is a dog.Where is she?".replace(reg,'IS');
//"He IS a boy .This IS a dog.Where IS she?"
修飾符
g
:global全文搜索,不添加,搜索到第一個匹配停止
"He is a boy .This is a dog.Where is she?".replace(/\bis\b/g,'IS')
"He IS a boy .This IS a dog.Where IS she?"
i
:ignore case 忽略大小寫,默認(rèn)大小寫敏感
"He Is a boy .This is a dog.Where is she?".replace(/\bis\b/gi,'hello')
"He hello a boy .This hello a dog.Where hello she?"
m
:multiple lines 多行搜索
var mulSrt = "@123\n@321\n@876"
mulSrt
"@123
@321
@876 "
mulSrt.replace(/@\d/g, "G")
"G23
G21
G76 "
mulSrt.replace(/^@\d/g, "G")
"G23
@321
@876 "
mulSrt.replace(/^@\d/gm, "G")
"G23
G21
G76 "
元字符
正則表達(dá)式由兩種基本字符類型組成:
原義文本字符
原義文本字符意思就是代表它本來含義的字符比如/a/
就是想匹配a
"jj abc a b c vf".replace(/a/gi,'hello')
//"jj hellobc hello b c vf"
寫/abc/
就是想匹配abc
"jj abc a b c vf".replace(/abc/gi,'hello')
//"jj hello a b c vf"
這些都是原義文本字符。
元字符
元字符實(shí)在正則表達(dá)式中有特殊含義的非字母字符
比如\b
它匹配的是單詞邊界,他的意思并不是匹配一個反斜線一個字母b,意思是匹配一個單詞邊界。這種就是特殊字符。
在正則表達(dá)式中有幾個字符需要注意他們都是有特殊含義的。
字符類
我們工作時希望并不是匹配某個字符,而是希望匹配符合一系列特征abc
。
我們可以使用元字符[]
來構(gòu)建一個簡單的類。
類就是符合某些特征的對象,是指一個泛指,而不是特指某個字符。
比如我們使用表達(dá)式[abc]
就把a(bǔ)或者b或者c自定義成為一類,表達(dá)式就可以匹配這類的字符。他的意思是有它們一個就行。
"a1b2c3".replace(/[abc]/g,'x')
//"x1x2x3"
這樣我們發(fā)現(xiàn)abc對應(yīng)的地方都進(jìn)行替換了,
字符來取反
使用元字符^
創(chuàng)建反向類/負(fù)向類
反向類的意思是不屬于某類的內(nèi)容
表達(dá)式[^abc]
表示不是字符a或b或c的內(nèi)容
"a1b2c3".replace(/[^abc]/g,'x')
//"axbxcx"
把字符a或b或c以為外的字符替換成x了
范圍類
正則表達(dá)式提供了范圍類
我們可以使用[a-z]
來鏈接兩個字符表示從a到z的任意字符
這是一個閉區(qū)間,也就是包含a和z本身
"a1b2c3x4z9".replace(/[a-z]/g,'Q');
//"Q1Q2Q3Q4Q9"
會發(fā)現(xiàn)a-z字母都被替換
在[]
組成的類內(nèi)部是可以連寫的[a-zA-Z]
"a1b2c3x4z9ASDFGGG".replace(/[a-zA-Z]/g,'Q');
"Q1Q2Q3Q4Q9QQQQQQQ"
匹配所有數(shù)字
"2016-11-12".replace(/[0-9]/g,'Q');
"QQQQ-QQ-QQ"
匹配所有數(shù)字和橫線
"2016-11-12".replace(/[0-9-]/g,'Q');
"QQQQQQQQQQ"
JS預(yù)定義類及邊界
正則表達(dá)式預(yù)定義類:
字符 | 含義 |
---|---|
. | 除了回車符和換行符之外的所有字符,等價于[^\r\n] |
\d | 數(shù)字字符,等價于[0-9] digit |
\D | 非數(shù)字字符,等價于[^0-9] |
\s | 空白符,等價于[\t\n\x0B\f\r] space |
\S | 非空白符,等價于[^\t\b\x0B\f\r] |
\w | 單詞字符(字母,數(shù)字,下劃線),等價于[a-zA-Z_0-9] word |
\W | 非單詞字符,等價于[^a-zA-Z_0-9] |
例子:
匹配一個ab+數(shù)字+任意字符
的字符串
/ab[0-9][^\r\n]/
"ab12334455sss".replace(/ab[0-9][^\r\n]/g,'Q');
//"Q334455sss"
或者
/ab\d.
"ab3klll".replace(/ab\d./g,"z")
//"zlll"
邊界
字符 | 含義 |
---|---|
^ | 以xxx開始 |
$ | 以xxx結(jié)束 |
\b | 單詞邊界 |
\B | 非單詞邊界 |
\b
單詞邊界
匹配字符
"This is a boy".replace(/is/g,'0')
//"Th0 0 a boy"
會發(fā)現(xiàn)所以 is
都被替換
如果想替換單詞,單詞前后是有單詞邊界,所以要寫上邊界"This is a boy".replace(/\bis\b/g,'0')
"This is a boy".replace(/\bis\b/g,'0')
//"This 0 a boy"
\B
非單詞邊界
如果想替換This
的is
,觀察下特征,發(fā)現(xiàn)前面并不是邊界,后面是邊界那就這樣寫"This is a boy".replace(/\Bis\b/g,'0')
"This is a boy".replace(/\Bis\b/g,'0')
//"Th0 is a boy"
^
以xxx為開始
"@123@abc@".replace(/@./g,'Q');
//"Q23Qbc@"
匹配全局@和任意字符
"@123@abc@".replace(/^@./g,'Q');
//"Q23@abc@"
以@和任意字符作為開始后面的不匹配
$
以xxx為結(jié)束
"@123@abc@".replace(/.@/g,'Q');
//"@12QabQ"
匹配全局任意字符和@
"@123@abc@".replace(/.@$/g,'Q');
//"@123@abQ"
匹配最后一個任意字符和@
var mulSrt = "@123\n@321\n@876"
mulSrt
"@123
@321
@876 "
mulSrt.replace(/@\d/g, "G")
"G23
G21
G76 "
mulSrt.replace(/^@\d/g, "G")
"G23
@321
@876 "
mulSrt.replace(/^@\d/gm, "G")
"G23
G21
G76 "
量詞
字符 | 含義 |
---|---|
? | 出現(xiàn)零次或一次(最多出現(xiàn)一次) |
+ | 出現(xiàn)一次或多次(至少出現(xiàn)一次) |
* | 出現(xiàn)零次或多次(任意次) |
{n} | 出現(xiàn)n次 |
{n,m} | 出現(xiàn)n到m次 |
{n,} | 至少出現(xiàn)n次 |
我們希望匹配一個連續(xù)出現(xiàn)20次數(shù)字的字符串
/\d\d\d\d\d\d\d\d..../反斜杠加d表示數(shù)字表示數(shù)字出現(xiàn)20次把他寫20遍這樣非常麻煩如果出現(xiàn)100次那就要寫100遍嗎。為了解決這個問題正則表達(dá)式引入了量詞的概念。
"12341111133333333111111111111".replace(/\d{20}/g,"d")
//"d111111111"
匹配數(shù)字兩次
"1234".replace(/\d{2}/g,"d")
//"dd"
JS正則貪婪模式與非貪婪模式
貪婪模式
了解了量詞我們看這樣一個場景。
/\d{3,6}/
數(shù)字匹配3到6次,我們用12345678
來執(zhí)行,我們寫的正則表達(dá)式是匹配數(shù)字3到6次,這個字符串中,即可以滿足3次4次5次6次,都是可以滿足的,那么正則表達(dá)式這時候該怎么處理?
正則表達(dá)式在處理的時候會盡可能多的匹配,直到匹配失敗。
"12345678".replace(/\d{3,6}/g,'A')
//"A78"
我們看到,他是匹配123456,78沒有匹配到,也就是說他是盡可能多的匹配而不是少的匹配。
這就是貪婪模式
非貪婪模式
讓正則表達(dá)式盡可能少的匹配,也就是說一旦匹配成功匹配不再繼續(xù)嘗試,就是非貪婪模式。
做法很簡單,在量詞后面加上?
即可。
"12345678".replace(/\d{3,6}?/g,'A')
"AA78"
這個時候的執(zhí)行結(jié)果就是123,456后面兩個78沒有被匹配到。
分組
匹配字符串Byron連續(xù)出現(xiàn)3次的場景。
沒有接觸量詞的時候我們把這個單詞寫3遍,接觸量詞之后我們可能會這樣寫Byron{3}
但是它代表的含義和我們預(yù)期的并不是一致的。實(shí)際上是n
重復(fù)3次,前面不重復(fù),量詞是作為緊挨著它的字符,并不是整個單詞,否則怎么知道你匹配到哪。
"ByronByronByron".replace(/Byron{3}/g,'A')
//"ByronByronByron"
"ByronnnByronByron".replace(/Byron{3}/g,'A')
//"AByronByron"
那么如何讓他匹配整個單詞呢?或者是我們?nèi)Χǖ膬?nèi)容,那么就用到分組
使用()
可以達(dá)到分組功能,使量詞作用于分組。
(Byron){3}
這樣寫就能達(dá)到我們預(yù)期效果。整個單詞重復(fù)了3遍。
比如想匹配一個小寫字母加一個數(shù)字連續(xù)出現(xiàn)3次a1b2c3d4
`a1b2c3d4`.replace(/[a-z]\d{3}/g,"A")
//"a1b2c3d4"
這樣寫是匹配不到的,因?yàn)?code>\d{3}是找數(shù)字出現(xiàn)3次的場景。
我們將他分組即可
`a1b2c3d4`.replace(/([a-z]\d){3}/g,"A")
//"Ad4"
這樣就達(dá)到效果了。這樣量詞作用于整個分組。
或
使用|
可以達(dá)到或的效果
"ByronCasper".replace(/Byron|Casper/g,"A");
//"AA"
這樣兩個都被匹配到了。
分組在或中的使用
"ByronsperByrCasper".replace(/Byr(on|Ca)sper/g,"A");
//"AA"
反向引用
比如我們想把2016-11-25
變成11/25/2016
如果只是想把-
替換成/
是很簡單的
"2016-11-25".replace(/-/g,'/')
//"2016/11/25"
但是它順序也變了,
以往的寫法
"2016-11-25".replace(/\d{4}-\d{2}-\d{2}/g,'11/25/2016')
//"11/25/2016"
但是需要匹配的值變成了2016,月份可能變成11,我們想替換他本身,替換的內(nèi)容不再是一個常量,而是一個變量。這個時候該怎么處理?
我們用反向引用,
"2016-11-25".replace(/(\d{4})-(\d{2})-(\d{2})/g,'$2/$3/$3')
"11/25/25"
我們用$
引用分組內(nèi)內(nèi)容,我們對分組內(nèi)容進(jìn)行捕獲,捕獲后用$1$2$3
來代替。
"2016-11-25".replace(/(\d{4})-(\d{2})-(\d{2})/g,'$1')
//"2016"
"2016-11-25".replace(/(\d{4})-(\d{2})-(\d{2})/g,'$2')
//"11"
"2016-11-25".replace(/(\d{4})-(\d{2})-(\d{2})/g,'$3')
//"25"
"2016-11-25".replace(/(\d{4})-(\d{2})-(\d{2})/g,'$2/$3/$3')
"11/25/25"
忽略分組
不希望捕獲某些分組,只需要在分組內(nèi)加上?:
就可以。
"abcaok".replace(/(abc).(ok)/g,'$1/$2')
//"abc/ok"
"abcaok".replace(/(?:abc).(ok)/g,'$1/$2')
//"ok/$2"
前瞻
正則表達(dá)式的前瞻:
- 正則表達(dá)式從文本頭部向尾部開始解析,文本尾部方向,成為“前”
- 前瞻 就是在正則表達(dá)式匹配到規(guī)則的時候,向前檢查是否符合斷言。比如找到兒子為張三,還得看看他的父親是否是李四
后顧/后瞻方向相反
注意:JavaScript不支持后顧
匹配單詞數(shù)字加數(shù)字
"a2*3".replace(/\w(\d)/g,"A");
//"A*3"
匹配單詞數(shù)字,注:這個單詞數(shù)字后面必須有數(shù)字才會匹配,(?=\d)
不能算在匹配內(nèi)容,這是斷言。
"a2*3".replace(/\w(?=\d)/g,"A");
//"A2*3"
寫個復(fù)雜點(diǎn)的案例
"a2*34v8".replace(/\w(?=\d)/g,"A");
//"A2*A4A8"
a2
*34``v8
這三個符合要求
"a2*34vv".replace(/\w(?=\d)/g,"A");
//"A2*A4vv"
a2
*34
vv,這里只有兩個匹配vv
v是對的但是它后面不是數(shù)字,所以不成功。
現(xiàn)在改一下比配后面不是數(shù)字的
"a2*34vv".replace(/\w(?!\d)/g,"A");
"aA*3AAA"
a2*``34``vv
,2變成A。4vv都符合所以是AAA
js對象屬性
描述 | 默認(rèn) |
---|---|
g:global是否全文搜索 | 默認(rèn)false |
i:ignore case是否大小寫敏感 | 默認(rèn)false |
m:multiline多行搜索 | 默認(rèn)值false |
lastIndex:當(dāng)前正則表達(dá)式匹配內(nèi)容的最后一個字符的下一個位置(即下一次匹配開始的位置)。 | |
source : 正則表達(dá)式的文本字符串。 |
test 和 exec方法
正則表達(dá)式本身的兩個方法
1.test
RegExp.prototype.test(str)
用于測試字符串參數(shù)中是否存在匹配正則表達(dá)式模式的字符串
如果存在則返回true,否則返回false
lastIndex 記錄當(dāng)前匹配結(jié)果的、最后一個字符的、下一個字符的位置
注意:test()方法在匹配的時候當(dāng)匹配到一個結(jié)果時,會從lastIndex位置開始匹配下一個結(jié)果,直到不存在的時候才置為0。因此,當(dāng)使用全局g屬性標(biāo)識時,當(dāng)匹配到最后一個結(jié)果時,lastIndex值指向不存在的位置,此時再執(zhí)行test()會返回false。
例子:多次執(zhí)行test()方法,會在true、false之間循環(huán)
(/\w/g).test('a')每次執(zhí)行都是正確的,但是通過實(shí)例化對象,需要很大的開銷
test()方法:原意就是測試有沒有、能不能匹配上,當(dāng)使用test原意時,沒必要加g
2.exec
RegExp.prototype.exec(str)
使用正則表達(dá)式模式對字符串執(zhí)行搜索,并將更新全局RegExp對象的屬性一反映匹配結(jié)果
如果沒有匹配的文本則返回 null,否則返回一個結(jié)果數(shù)組:
- index 聲明匹配文本的第一個字符位置
- input 存放被檢索的字符串 string
非全局調(diào)用
調(diào)用非全局的RegExp對象的 exec()時,返回數(shù)組
第一個元素是與正則表達(dá)式相匹配的文本
第二個元素是與RegExpObject的第一個子表達(dá)式相匹配的文本(如果有的話)
第三個元素是與RegExp對象的第二個子表達(dá)式相匹配的文本(如果有的話),以此類推
字符串對象方法
String.prototype.search(reg)
search() 方法用于檢索字符串中指定的子字符串,或檢索與正則表達(dá)式相匹配的子字符串。
語法
stringObject.search(regexp)
參數(shù) | 描述 |
---|---|
regexp | 該參數(shù)可以是需要在 stringObject 中檢索的子串,也可以是需要檢索的 RegExp 對象。注釋:要執(zhí)行忽略大小寫的檢索,請追加標(biāo)志 i。 |
返回值
stringObject 中第一個與 regexp 相匹配的子串的起始位置。
注釋:如果沒有找到任何匹配的子串,則返回 -1。
說明
search() 方法不執(zhí)行全局匹配,它將忽略標(biāo)志 g。它同時忽略 regexp 的 lastIndex 屬性,并且總是從字符串的開始進(jìn)行檢索,這意味著它總是返回 stringObject 的第一個匹配的位置。
"a1b1c1d1".search('1')
//1
"a1b1c1d1".search('10')
//-1
"a1b1c1d1".search(1)
//1
"a1b1c1d1".search(/1/)
//1
String.prototype.match(reg)
match() 方法可在字符串內(nèi)檢索指定的值,或找到一個或多個正則表達(dá)式的匹配。
該方法類似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。
參數(shù) | 描述 |
---|---|
searchvalue | 必需。規(guī)定要檢索的字符串值。 |
regexp | 必需。規(guī)定要匹配的模式的 RegExp 對象。如果該參數(shù)不是 RegExp 對象,則需要首先把它傳遞給 RegExp 構(gòu)造函數(shù),將其轉(zhuǎn)換為 RegExp 對象。 |
返回值
存放匹配結(jié)果的數(shù)組。該數(shù)組的內(nèi)容依賴于 regexp 是否具有全局標(biāo)志 g。
說明
match() 方法將檢索字符串 stringObject,以找到一個或多個與 regexp 匹配的文本。這個方法的行為在很大程度上有賴于 regexp 是否具有標(biāo)志 g。
如果 regexp 沒有標(biāo)志 g,那么 match() 方法就只能在 stringObject
中執(zhí)行一次匹配。如果沒有找到任何匹配的文本, match() 將返回
null。否則,它將返回一個數(shù)組,其中存放了與它找到的匹配文本有關(guān)的信息。該數(shù)組的第 0
個元素存放的是匹配文本,而其余的元素存放的是與正則表達(dá)式的子表達(dá)式匹配的文本。除了這些常規(guī)的數(shù)組元素之外,返回的數(shù)組還含有兩個對象屬性。index
屬性聲明的是匹配文本的起始字符在 stringObject 中的位置,input 屬性聲明的是對 stringObject 的引用。
如果 regexp 具有標(biāo)志 g,則 match() 方法將執(zhí)行全局檢索,找到 stringObject
中的所有匹配子字符串。若沒有找到任何匹配的子串,則返回
null。如果找到了一個或多個匹配子串,則返回一個數(shù)組。不過全局匹配返回的數(shù)組的內(nèi)容與前者大不相同,它的數(shù)組元素中存放的是
stringObject 中所有的匹配子串,而且也沒有 index 屬性或 input 屬性。
注意:在全局檢索模式下,match() 即不提供與子表達(dá)式匹配的文本的信息,也不聲明每個匹配子串的位置。如果您需要這些全局檢索的信息,可以使用 RegExp.exec()。
var str="Hello world!"
document.write(str.match("world") + "<br />")
document.write(str.match("World") + "<br />")
document.write(str.match("worlld") + "<br />")
document.write(str.match("world!"))
輸出
world
null
null
world!
正則方法非全局匹配
var reg3 = /\d(\w)/;
var reg4 = /\d(\w)/g;
var ts = '$1a2b3c4d5e';
var ret = ts.match(reg3);
console.log(ret); //["1a", "a", index: 1, input: "$1a2b3c4d5e"]
document.write(ret); //1a,a
正則方法全局匹配
var reg3 = /\d(\w)/;
var reg4 = /\d(\w)/g;
var ts = '$1a2b3c4d5e';
var ret = ts.match(reg4);
console.log(ret); //["1a", "2b", "3c", "4d", "5e"]
document.write(ret);//1a,2b,3c,4d,5e
String.prototype.match(reg)方法
split() 方法用于把一個字符串分割成字符串?dāng)?shù)組。
基本用法
var op = 'a,b,c,d';
var spo = op.split(',');
console.log(spo);
//["a", "b", "c", "d"]
在一些復(fù)雜分割情況下可以用正則用法
var op = 'a1b2c3d';
var spo = op.split(/\d/);
console.log(spo);
//["a", "b", "c", "d"]
再復(fù)雜
var op = 'a,b|c?d';
var spo = op.split(/[,|\|\?]/g);
console.log(spo);
//["a", "b", "c", "d"]
String.prototype.replace方法
傳入兩個參數(shù)replace(找誰,替換誰)
"a1b".replace(/1/,2)
//"a2b"
"a1b1c1".replace(/1/g,2)
//"a2b2c2"
"a1b1c1".replace(/\d/g,2)
"a2b2c2"
如果我想把"a1b2c3d4" => "a2b3c4d5"該怎么實(shí)現(xiàn)呢?
var h = "a1b2c3d4".replace(/\d/g, function(match, index, origin) {
//console.log(index);
return parseInt(match) + 1;
});
console.log(h);//a2b3c4d5
var h = "a1b2c3d4e5".replace(/(\d)(\w)(\d)/g, function(match, g1, g2, g3, index, origin) {
//console.log(index);
return g1 + g3;
});
console.log(h);//a12c34e5