1. 程式人生 > >29.22分鐘學會書寫正則(2)

29.22分鐘學會書寫正則(2)

寫在前面的一些廢話

沒有看過上一篇文章的盆友有福了!

今天!沒錯!就是現在!我將免費!all f*cking FREE!

免費將上篇文章的連結發出來!

這裡是上篇

上回說了怎麼寫出正則,這次展示下在js中使用正則的場景

正則物件屬性

javascript的正則物件有以下幾個屬性,其中前面三個也叫修飾符(也就是/表示式/兩條槓後面的字元,比如上一篇文章出現的 /\bis\b/g 的這個g)。

  • global:是否全文搜尋,預設false
  • ignoreCase:是否大小寫敏感,預設false,即不忽略大小寫
  • multiline:是否多行搜尋,預設false
  • lastIndex:當前表示式匹配內容的最後一個字元的下一個位置
  • source:正則表示式的文字字串,也就是“/表示式/修飾符”中的表示式,var reg=/\bis\b/g; reg.source就是\bis\b

正則相關的方法

js中,RegExp物件有兩個內建方法

  • test
  • exec

此外,還有一些String物件的方法也支援正則表示式,它們是

  • search
  • match
  • split
  • replace

test()

test() 方法用於檢測一個字串是否匹配某個模式,返回true或者false.

var reg = /\w/;
reg.test('abc');
//true
reg.test('abc');
//true
reg.test('abc');
//true
reg.test('@#$%')
//false
reg.test('@#$%')
//false
//為什麼要多執行幾遍呢?你可能會以為樓主lu多了導致老眼昏花多輸入了幾遍。but NO!多執行幾遍是為了和下面作對比。

當我們的正則表示式加上了g修飾符以後,這個方法出現了一些不同

var reg = /\w/g;
reg.test('abc');//true
reg.test('abc');//true
reg.test('abc');//true
reg.test('abc');//false

clipboard.png
為什麼會這樣呢?因為當我們加上全域性搜尋這個修飾符後,test()方法會返回結果,並且更新reg物件的屬性(lastIndex),他會在上一次lastIndex的位置開始往後查詢,而不是從頭開始。
所以這個方法建議不要加g,如果你這個人比較倔強,非要加的話,你可以每次都重新初始化一個正則物件,因為它第一次的結果是和沒有加g的時候是一樣的。
Like this。

var reg = /\w/g;reg.test('abc');//true
//每次都初始化正則物件,把這兩行寫在一行裡比較好複製,因為分開復制一不小心就出現了上面的問題

exec()

exec()方法用於使用正則表示式對字串執行搜尋,並將更新全域性RegExp物件的屬性以反應匹配結果
如果沒有匹配到文字則返回null,否則返回一個結果陣列:

  • 陣列第一個元素是與正則表示式相匹配的文字
  • 第二個元素是與正則表示式的第一個子表示式(也就是分組1)相匹配的文字(如果有分組1的話)
  • 第三個元素是與正則表示式的第二個子表示式(分組2)相匹配的文字(如果有分組2的話)
  • 除了陣列元素和 length 屬性之外,exec() 方法還返回兩個屬性。index 屬性宣告的是匹配文字的第一個字元的位置。input 屬性則存放的是被檢索的字串 string。
var reg = /(\d)(\w)/  //上篇文章已經介紹過分組了,這裡的兩個括號分別是分組1和分組2
reg.exec('1a2b3c4d5e');

clipboard.png

當我們的正則表示式加上了g修飾符以後,這個方法又出現了一些不同

var reg = /(\d)(\w)/g
reg.exec('1a2b3c4d5e');

還是上圖片比較簡單~
clipboard.png
這個表現跟test是一個尿性的,即非全域性呼叫(不加g)的時候不會更新lastIndex(lastIndex不生效),全域性呼叫的時候會更新lastIndex

說完了比較複雜的有分組的情況,我們來看看沒有分組的情況,言簡意賅,你作為這麼優秀的一個人,應該能隨便看懂吧。

var reg = /\d\w/  
reg.exec('1a2b3c4d5e');

clipboard.png

對於這個方法呢,如果我們只需要查詢第一個匹配結果的話可以不加g,如果需要返回所有匹配結果的話,需要迴圈執行reg.exec(),並且需要加上g。

search()

search()方法用於檢索字串中制定的子字串或者檢索與正則表示式相匹配的子字串。

方法返回第一個匹配結果的index,查詢不到返回-1
search()方法會忽略g標誌,總是從字串的開頭進行檢索

當我們傳入的引數s字串時,它會轉換成正則表示式
var str = "abcd1234"
str.search('1') //4
str.search(/1/) //4
str.search('hello') //-1
str.search(/hello/) //-1

so easy~下一個

match()

非全域性呼叫情況下(不加g):
這個方法類似於exec(),返回值是一毛一樣的,one hair one style。
match()方法可在字串內檢索指定的值,或找到一個或多個正則表示式的匹配
如果沒有匹配到文字則返回null,否則返回一個結果陣列:

  • 陣列第一個元素是與正則表示式相匹配的文字
  • 第二個元素是與正則表示式的第一個子表示式(也就是分組1)相匹配的文字(如果有分組1的話)
  • 第三個元素是與正則表示式的第二個子表示式(分組2)相匹配的文字(如果有分組2的話)
  • 除了陣列元素和 length 屬性之外,match() 方法還返回兩個屬性。index 屬性宣告的是匹配文字的第一個字元的位置。input 屬性則存放的是被檢索的字串 string。
var str = "1a2b3c4d";
var reg = /(\d)(\w)/;
str.match(reg);

clipboard.png

當我們的正則表示式加上了g修飾符以後,這個方法又出現了一些不同,我為什麼要說‘又’

match()方法的返回改變了,變化害...害挺大的,跟前面的exec()和test()方法又有不同

如果沒有匹配到文字則返回null,否則返回一個結果陣列:

  • 陣列元素為與正則表示式匹配的文字
var str = "1a2b3c4d";
var reg = /(\d)(\w)/g;
str.match(reg);

clipboard.png

你有沒有發現,即使我已經貼了圖,卻還是寫了程式碼,為什麼?
因為作為一個這麼sweet 和 warm的人,我有必要為你節省你自己輸入程式碼的時間,你現在只需要ctrl C 然後ctrl V就可以在瀏覽器控制瘋狂驗證我的圖片,瘋狂測試這些方法!

split()

split()方法用於把一個字串分割成字串陣列。

//這個也可以輸入字串作為引數,類似於search(),它會轉換成正則
var str = "a,b,c,d"
str.split(','); //["a","b","c","d"]
str.split(/,/); //["a","b","c","d"]
//一般情況都是使用字串居多,比較複雜的情況就可以使用正則
var str ="a1b2c3";
str.split(/\d/); //["a", "b", "c", ""]
//注意:如果字串最後的子字串剛好符合引數的正則,那麼就會多了一個空的元素,像上面一樣

replace()

來了來了,上篇文章中使用最多的replace()終於來了!!!AV8D shout with me! RRRRRRRRrrrrrrrrrrrrrr~EEEEEEE~PPPPP~LLLL~AAAA~CCCCC~EEEEE。

該方法用於在字串中用一些字元替換另一些字元,或替換一個與正則表示式匹配的子串。

1、 一般用法,這裡是一般用法啊,replace('找誰','替換成誰')

該用法的全域性與非全域性呼叫的差別是‘替換第一個匹配項’和‘替換所有匹配項’。

舉個常用的例子

//這個‘找誰’同樣也可以是字串或者是正則,類似於split(),search()
var str = "hello I am leelei";
str.replace('leelei','嶺南吳彥祖'); //"hello I am 嶺南吳彥祖"
str.replace(/leelei/,'嶺南吳彥祖'); //"hello I am 嶺南吳彥祖"

好吧,這個對於你們來說並不常用,可能是隻有我在用而已,抱歉。寫個你們常用的例子吧

var str = "2018-11-26";
str.replace(/-/,'/');  //"2018/11-26"
//看到沒有,這裡只替換了一個-
str.replace(/-/g,'/');  //"2018/11/26"
//只有全域性呼叫的時候,才會替換所有的匹配文字

2、 進階用法,replace('找誰',回撥函式),每次匹配替換的時候呼叫,有4個引數

  • 1、匹配的字串
  • 2、正則表示式分組內容,沒有分組就沒有這個這個引數,幾個分組就幾個該引數
  • 3、匹配項在字串中的index
  • 4、原字串,replace()方法不會改變原字串的哦。
//**當沒有分組的時候**
var str ="a5b6c7d8";
//可以根據下面的截圖對照上面的引數來理解記憶。
//這裡是給每一個匹配的數字+1.
str.replace(/\d/g,function(match,index,origin){
    console.log(match,index,origin);
    return match-0+1;
});

clipboard.png

//**當有分組的時候**
//為字串中的某些欄位更換樣式,完整的demo就不寫了,大家應該都能看懂吧。
//將第一個分組匹配的內容替換掉
//為什麼要分組? 因為我們不想給'個'這個字新增樣式,但是又需要用'個'來判斷,我們只更改'個'前面的數字的樣式,不更改其他數字。
var str = "第1點,這裡有4個橘子,5個橙子,9個蘋果,我們需要為這幾個數量更改樣式.";
str.replace(/(\d)個/g,function(match,$1,index,origin){
    console.log(match,$1);
    return "<span style='color:red'>"+$1+"<span>個";
})
//需要注意的是,這個回撥函式的return值會覆蓋match的值,因此要在return的時候加回'個'字。

clipboard.png
ok~應該足夠清楚了吧~

最後

雖然標題是29.22分鐘,但是看完兩篇文章好像就不止了。
我不管,30分鐘內沒看完的好好檢討下自己,是不是沒有戴眼鏡,是不是沒睡好覺,看那麼慢呢!

如果有建議或者意見,請在評論區指出,非常感謝~