JavaScript正則,看這篇就夠了

寫在前面

正則的使用,相信你們工做中經常使用到的莫過於,表單驗證:驗證用戶輸入的內容是否符合咱們設定的規則,例如:郵箱、電話、密碼...,固然公司業務不一樣,手寫能力強同窗也能夠用數據採集:在一堆數據中把咱們須要的數據獲取到,今天順帶總結一下,例如::javascript

  • URL傳參(問號傳參) 從列表頁到詳細頁(或者其餘的頁面),咱們點擊不一樣的列表,在詳細頁面看到的內容也不一樣,可是詳細頁是同一個頁面,想要展現不一樣的內容,須要把URL地址中的,?後面傳遞進來的參數獲取到,經過傳遞過來的參數值的不同展現不一樣的內容
  • 信息採集:把一些數據轉變爲咱們想要的格式,例如:"2018-4-3 12:14:00" ->"2016年04月03日"

今天順帶總結一下; 正則是什麼 正則就是用來處理字符串的:匹配字符串的格式是否符合既定的格式(正則的匹配)、把一個字符串中符合既定格式的內容獲取到(正則的捕獲); test和exec是正則裏面的方法 test->匹配java

var reg = /\d/;//-> \d一個0-9之間的數字 ->包含一個0-9之間的數字的規則
       console.log(reg.test("2016"));//->true
       console.log(reg.test("duff990fff"));//->true
       console.log(reg.test("dufffff"));//->false
複製代碼

exec->捕獲正則表達式

var reg = /\d/g;
       console.log(reg.exec("2016"));//->["2", index: 0, input: "2016"]
       console.log(reg.exec("2016"));//->["0"...]
       console.log(reg.exec("2016"));//->["1"...]
       console.log(reg.exec("2016"));//->["6"...]
複製代碼

正則的組成 每一個正則都是由元字符和修飾符兩部分組成, 「/」裏面的 內容稱爲元字符 「/」 [修飾符]g、i、m數組

g(global)->全局匹配
    i(ignoreCase)->忽略大小寫匹配
    m(multiline)->換行匹配
複製代碼

正則經常使用的元字符

如下列出的都是經常使用的元字符,若是是不瞭解的童鞋須要,浪費你10分鐘時間記一下,終身受益哈~ 元字符:只要在//之間包含的全部的字符都是元字符bash

1)具備特殊意義的元字符ui

\d -> 匹配一個0-9的數字,至關於[0-9],和它相反的是\D ->匹配一個除了0-9的任意字符
       \w -> 匹配一個0-九、a-z、A-Z、_的數字或字符,至關於[0-9a-zA-Z_]
       \s -> 匹配一個空白字符(空格、製表符...)
       \b -> 匹配一個單詞的邊界
       \t -> 匹配一個製表符
       \n -> 匹配一個換行
       . -> 匹配一個除了\n之外的任意字符
       ^ -> 以某一個元字符開頭
       $ -> 以某一個元字符結尾
       \ -> 轉義字符
       x|y -> x或者y的一個
       [xyz] -> x、y、z中的任意一個
       [^xyz] -> 除了xyz中的任意一個字符
       [a-z] -> 匹配a-z中的任意一個字符
       [^a-z] -> 匹配除了a-z中的任意一個字符
       () -> 正則中的分組
複製代碼

2)表明出現次數的"量詞元字符"spa

->+ : 出現一到屢次
    ->* : 出現零到屢次
    ->? : 出現零到一次
    ->{n} : 出現n次
    ->{n,} : 出現n到屢次
    ->{n,m} : 出現n-m次
複製代碼

小試牛刀code

-> ^/$
       var reg = /\d+/;//->包含一到多個數字(0-9)便可
       console.log(reg.test("duffy2016"));//->true

       reg = /^\d+$/;//->只能是一到多個數字
       console.log(reg.test("duffy2016"));//->false
       console.log(reg.test("2016"));//->true
複製代碼
-> .
       var reg = /^2.6$/;
       console.log(reg.test("2.6"));//->true
       console.log(reg.test("2@6"));//->true
    
       reg = /^2\.6$/;//->\是轉義字符:把.這個特殊意義(任意字符)的元字符轉變爲只表明自己意義(小數點)的一個普通元字符
       console.log(reg.test("2.6"));//->true
       console.log(reg.test("2@6"));//->false
複製代碼
//->[]
    //->在中括號中出現的全部字符(無論以前表明什麼意思),在這裏都是隻表明自己的意思
    //var reg = /^[2.3]$/;//->.這裏只表明小數點,不是任意字符了
    //reg = /^[\dz]$/;//->\d自己總體就是0-9之間的數字,在這裏仍是這個意思
複製代碼
//->在中括號中出現的兩位數不是一個兩位數,而是左邊或者右邊的
//var reg = /^[10-23]$/;//->1或者0-2或者3
複製代碼
在中括號中"-"具備連字符的做用,若是隻想表示-,須要把其放在末尾
    //var reg = /^[12-]$/;

    //->中括號自己也有特殊的意思,若是須要只表明中括號自己的意思,須要進行轉義
    //var reg = /^\[\d+\]$/;//->"[200]"
複製代碼
//->x|y
//var reg = /^1|2$/;//->和這個有區別:/^[12]$/
//->一、二、12
複製代碼
//var reg = /^10|28$/;
    //->十、2八、102八、10二、10八、12八、028 ->不是咱們想要的那個10或者28了

複製代碼

()分組:把一個大正則劃分紅幾個小正則 1)改變正則的默認優先級orm

//var reg = /^(10|28)$/;//->10或者28
複製代碼

2)分組的第二個做用:分組引用對象

"wood" "foot" "week" "feel" "door" "food" "good" "cool"...
    var reg = /^[a-z]([a-z])\1[a-z]$/i;//->\1出現和第一個分組如出一轍的內容
複製代碼

五、建立一個正則也有兩種方式:字面量方式、實例建立的方式

//->實例建立第一參數值是字符串
    //->想要和字面量方式保持統一的話,對於\d \w \n...這些都須要多加一個\,使其\d具備本身的特殊的意義
  var reg = /^\d+$/ig;
console.log(reg.test("2016"));//->true
reg = new RegExp("^\d+$", "ig");
console.log(reg.test("2016"));//->false
reg = new RegExp("^\\d+$", "ig");
console.log(reg.test("2016"));//->true
複製代碼
//->對於[]、()這類的是沒有區別的
    //    var reg = /^[0-9]$/;
    //    console.log(reg.test("0"));//->true
    //    reg = new RegExp("^[0-9]$");
    //    console.log(reg.test("0"));//->true

    //->在實例建立的方式中,咱們只要出現\,基本上都是要寫\\的
    //    var reg = /^\[100\]$/;
    //    console.log(reg.test("[100]"));//->true
    //    reg = new RegExp("^\[100\]$");
    //    console.log(reg.test("[100]"));//->false
    //    reg = new RegExp("^\\[100\\]$");
    //    console.log(reg.test("[100]"));//->true
複製代碼

當一個正則表達式中須要把一個變量的值做爲一個動態的規則:咱們只能使用實例建立的方式 // var reg = /^duffy"+num+"peixun$/;//->在//之間包起來的都是元字符,有的是特殊的,有的就是表明自己意思的 ->以z開頭,hufeng,出現一到多個",nu,出現一個到一個m,",peixun ->總之一句話:字面量方式中不存在什麼字符串,也就沒有所謂的字符串拼接,把變量的值拼接過來這一說了

//    console.log(reg.test("duffy2016peixun"));//->false

    //    var num = 2016;
    //    var reg = new RegExp("^duffy" + num + "peixun$");
    //    console.log(reg.test("duffy2016peixun"));//->true
複製代碼
//字面量建立出來的是基本數據類型的值(不是嚴謹的實例,由於不能使用instanceof 檢測是不是Number的實例),實例建立出來的是對象數據類型的值
//    var num = 12;
//    var num = new Number(12);
複製代碼

經常使用的正則表達式

一、手機號:11位數字、都是以1開頭的

var reg = /^1\d{10}$/;

二、真實姓名(中國):兩到四位的漢字

var reg = /^[\u4e00-\u9fa5]{2,4}$/;

三、驗證郵箱

// 1633397595@qq.com
// 1633397595@163.com.cn
// 1633397595@163.com
// duffy_youxiang@tengxu.cn
//var reg7 = /^[\w.-]+@$/  //@分解兩邊 左邊任意,\w 數字,大小寫字符_ - . 右邊
var reg7 = /^[\w.-]+@([1-9]|[a-z]|[A-Z])+(\.[A-Za-z]{2,4}){1,2}$/
console.log(reg7.test('1633397595@qq.com'))
複製代碼

四、驗證有效數字的

0 -12 -12.3 -12.0 12.3 12.0
    ->可能出現"-"也可能不出現,出現的話只能出現一次
    ->整數部分是一到多個數字,可是兩位數及以上的話不能以0開頭
    ->小數部分可能有可能沒有,一但有必須是 .後面跟一位或者多位數字
    var reg = /^-?(\d|([1-9]\d+))(\.\d+)?$/;
複製代碼

五、年齡:18-65之間

18-19  /^1(8|9)$/
    20-59  /^[2-5]\d$/
    60-65  /^6[0-5]$/
    var reg = /^((18|19)|([2-5]\d)|(6[0-5]))$/;
複製代碼

正則的捕獲

正則的捕獲分爲兩個階段: 匹配:首先驗證字符串和正則是否匹配,不匹配的話捕獲到的結果爲null

var str = "dafei";
       var reg = /\d+/;
       console.log(reg.exec(str));//->null
複製代碼

捕獲:把正則匹配到的內容捕獲到:捕獲到的結果是一個數組,數組第一項是當前正則匹配捕獲的內容,index:捕獲的開始索引位置,input:捕獲的原始字符串 每一次執行exec只能捕獲到一個匹配的,想把全部匹配的都捕獲到,至少要執行屢次 ->可是通常狀況下,咱們無論執行多少次,每一次捕獲的內容都是和第一次如出一轍,後面的2017是捕獲不到的 "正則捕獲的懶惰性"

var str = "duffy2016peixun2017";
       var reg = /\d+/;
       console.log(reg.exec(str));//->["2016", index: 7, input: "duffy2016peixun2017"]
       console.log(reg.exec(str));//->["2016"...]
複製代碼

爲啥會出現懶惰性? reg.lastIndex:正則每一次捕獲的時候,在字符串中開始查找的索引, 正則每一次捕獲結束後,默認的沒有把lastIndex值進行修改,lastIndex一直是零,致使第二次捕獲仍是從字符串的起始位置開始查找,致使每一次捕獲的都是第一個和正則匹配的

var str = "duffy2016peixun2017";
       var reg = /\d+/;
       console.log(reg.lastIndex);//->0 捕獲的時候是從字符串開始的位置進行查找的
       console.log(reg.exec(str));//->["2016"...]
       console.log(reg.lastIndex);//->0 第二次捕獲的話仍是從字符串索引爲零的位置開始查找
       console.log(reg.exec(str));//->["2016"...]
複製代碼

有n個的匹配的就須要執行n次exec這個方法,比較的麻煩,生活如此美好,何須這麼麻煩? ->字符串中提供了一個叫作match的方法,這個方法能夠一次執行把全部匹配的捕獲到

var str = "duffy2016peixun2017";
       var reg = /\d+/g;//->無論用哪一個方法,g是不能少的
       console.log(str.match(reg));//->["2016", "2017"]
複製代碼

可是match也有本身的侷限性? 若是正則中出現分組,並且須要執行屢次exec才能所有捕獲的,使用match不能把分組的內容捕獲到.最佳解決方案 ---replace,replace天生爲正則而生

複製代碼

實戰

格式化時間字符串

var str = "2016-04-03";//->"2016年04月03日"
let reg = /^([1-9]\d{3})-(0?[1-9]|1[1-2])-([02]\d|[3][0-1])$/
console.log(reg.test(str))
str.replace(reg,function(){
  console.log(arguments)
  return arguments[1] + '年' + arguments[2] + '月' + + arguments[3] + '日'
})

function format(str) {
  var reg = /^([1-9]\d{3})-(0?[1-9]|1[1-2])-([02]\d|[3][0-1])$/g
  if (!reg.test(str)) return '輸入日期格式不合法'
  return (str.replace(reg,function(){
    // console.log(arguments)
    return arguments[1] + '年' + arguments[2] + '月' + + arguments[3] + '日'
  }))
}
console.log(format('2018-12-30'))   -> '2018年12月30日 複製代碼

數字大寫轉換

var str = "123678";//->"壹貳叄陸柒捌"
       var ary = ["零", "壹", "貳", "叄", "肆", "伍", "陸", "柒", "捌", "玖"];
       str = str.replace(/\d/g, function () {
           //console.log(arguments[0]);//->每一次捕獲到的內容(咱們要的數字)
           return ary[arguments[0]];
       });
       console.log(str);
複製代碼

簡易模板引擎實現的原理

var data = ['duffy', '27', 'china', 'javascript']
var str = "my name is {0},my age is {1},i com from {2},i can do {3}~~";

var reg = /\{(\d)\}/g
console.log(reg.test(str))
str = str.replace(reg, function(){
  return data[arguments[1]]
})
複製代碼
相關文章
相關標籤/搜索