如何學正則(告別複製粘貼)

知識學到本身手裏的纔是本身的,若是複製,粘貼別人的對本身幫助並不大,它只能幫本身解決一時的問題(有時還要花費本身大量的時間來查找),而不能從根本上解決問題。git

就好像前段時間個人的大學同窗問了我一個正則問題,如何驗證用戶輸入的密碼必須包含字符、數字、特殊符號,他說在百度上找了大量的正則示例都不能解決問題,我就問而後呢,他給我說我問你,我當時就無語了,我當時由於正在作項目,一時沒想出來,我跟他說你沒試着換個思路,暫時沒有找到用一個正則解決這個問題的你就不會試着分別對字符,數字,特殊字符單獨判斷,而後進行與運算不就好了,再者說了從用戶體驗上用一個正則判斷後給出一個結果,用戶體驗也很差,應該針對用戶輸入不一樣的狀況給出不一樣的提示信息,若是密碼的組成沒有數字,就提示沒有數字,若是沒有字符就提示沒有字符...... , 若是以此類推以爲判斷過多,你能夠再簡化處理,如只有密碼組成包含兩種,就提示缺乏的一種,若是密碼組成只包含一種,就提示密碼應該有字符、數字、特殊符號組成。github

這無形中給我上了生動的一課,正則不只其餘人忽視了,我也忽視了,有所欠缺。因此儘管最近在努力拿下設計模式這個高地,仍是決定抽出一部分時間梳理一下本身的正則知識的掌握。正則表達式

具備特殊含義的字符

下面只列出經常使用的字符,以及我我的對它們的分類。設計模式

分組和集合

  • () : 括號內的表達式表示一個分組
  • [] : 方括號內的表達式表示一個集合

運算符

  • ^ : 若是出如今集合([])中表示取反,不然是是定位符,從字符串的前邊界開始匹配
  • | :它表示或的意思,就是起到或運算的做用
  • ?: : 它的做用是放在第一個選項前來消除相關匹配會被緩存這種反作用

定位符

  • ^ : 上面已經說了它定義正則運算的前邊界
  • $ : 它定義了正則運算的後邊界
  • \b : 匹配一個字符的邊界(也便是字符和空白字符的分界)

字符類(表明一類字符)

  • \d : 表明數字,而 \D ,非數字
  • \w : 表明單詞,而 \W ,非單詞
  • \s : 表明空白符,而 \D ,非空白字符
  • . : 任意字符

限定符

它是用來指定匹配結果的長度或次數。數組

匹配該符號前面的表達式緩存

  • + : 一次或更屢次微信

  • * :零次或屢次微信開發

  • : 零次或一次app

  • {} : 匹配次數與話括號內的值有關。dom

    若是 {n} ,就是匹配n次; 若是 {n,} ,就是匹配至少n次; 若是 {n,m} ,就是匹配n到m之間的任意次數。

如何玩轉正則

正則用在字符串的處理上,能夠減小咱們的js代碼的書寫量,優化咱們的代碼,同時對於咱們學習別人源碼中複雜的正則已有幫助。

下面是一張來自知乎關於你是如何學會正則表達式的?問題的一張圖,掌握這張圖的正則,大概你就能解決你所面臨的大部分問題。

regular

/^\s*[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*\s*$/
複製代碼

下面推薦幾款可視化的正則編輯器。

regexper (這是我最先接觸到的一款)

Regulex (這一款是我如今常用的)

RegExr (這一款功能很強大,對於學習正則頗有幫助,若是學習正則的話強烈推薦)

js如何使用

正則是一個很強大的字符串查詢和替換的方法。

之前咱們有時侯老是在想將字符串轉換爲數字數組,利用數組的方法來處理字符,可是要知道字符串就是咱們在生活和工做中常見的形式,數字、數組、Boolean類型的相對較少,尤爲是最近在作微信開發時發現正則很重要,我同窗的例子,只是給了我一個深刻學習和研究的動力,這只是個人初步總結,之後有必要的話還會增強。

在JavaScript中咱們使用 RegExp 來建立一個對象來實現正則表達式。

基本定義

一個正則有兩部分組成:正則主體和修飾符。

形式以下:

regExp = new RegExp('pattern', 'flag');

// 或者
regExp = /pattern/gmi
複製代碼

正則的修飾符一共有5種,分別爲:

  • g : 全部匹配的狀況,若是沒有它,只一種匹配狀況
  • i : 忽略字符的大小寫
  • m : 支持多行
  • u : 支持 Unicode
  • y : 嚴格模式(返回指定位置後的匹配結果)

正則對象的一些方法

regexp.test(str)

test 方法返回值爲true/false

let str = "Hello world!";
let regexp = /hello/i;
console.log(regexp.test(str));
複製代碼
regexp.exec(str)

因爲這個方法很差用,因此不多有人使用。

let str = "Hello world!";
let regexp = /l(o)/ig; // 若是用exec返回全部的的匹配結果須要加上 ‘g’ 修飾符
let matchOne = regexp.exec(str);
console.log(matchOne[0]); // lo
console.log(matchOne[1]); // o
console.log(matchOne.index); // 3
console.log(matchOne.input); // Hello world!
console.log(matchOne.lastIndex); // 5
複製代碼

若是沒有匹配返回null

js中String可使用正則的方法

在String的方法中使用正則,能夠輕鬆的解決咱們平常開發中的問題。

str.search()

若是有匹配結果,返回第一個匹配結果的首字符位置;不然,返回 `-1`。

let str = "Hello world!";
regexp = /o/i;
str.search(regexp); // 4
複製代碼

注;search 只能返回第一次匹配的結果,而不能返回其餘匹配結果

str.match(str|reg)

let str = "Hello world!";
regexp = /o/i;
let result = str.match(regexp);

console.log(result[0]); // o
console.log(result.index); // 4
console.log(result.input); // Hello world!
複製代碼

咱們發現 str.match() 的用法和 regexp.exec() 返回的結果很同樣,其實match的底層實現就是 regexp.exec(),使用也同樣,注意修飾符 g

str.split(reg|substr, limit)

將給定的字符串按單詞爲單位進行分割,返回一個由單詞組成的數組。

let str = 'Hello world, my   name  is lzb.'
let regexp = /\s+/i;
str.split(regexp); // ["Hello", "world,", "my", "name", "is", "lzb."]
str.split(regexp, 3) //  ["Hello", "world,", "my"]
複製代碼

在這個字符串的方法中第二參數限制返回結果數組的長度。

在返回的結果中,咱們發現有的單詞帶有特殊符號,下面一個字符串方法將實現清除特殊符號。

str.replace(str|reg, str|func)

若是要實現上面示例的清除字符中特殊符號的目標,咱們可使用 str.replace() ,效果以下:

let str = 'Hello world, my   name  is lzb.'
let regexp = /[.,\/#!$%\^&\*;:{}=\-_`~()]/g;
str.replace(regexp, ''); // "Hello world my   name  is lzb"

或者

let str = 'Hello world, my   name  is lzb.'
let regexp = /[^\w\s|-]/g;
str.replace(regexp, ''); // "Hello world my   name  is lzb"
複製代碼

而後,接着使用上面的 str.split() 方法便可,或者有同窗可能想到以下方法:

let str = 'Hello world, my   name  is u-lzb.'
let regexp = /[^\w]+/g;
str.split(regexp); // ["Hello", "world", "my", "name", "is", "u", "lzb", ""]
複製代碼

這種方法不建議使用,問題很明顯,這裏就很少說了。

咱們發現上面實現清除字符串中特殊符號的方法有兩種,這兩種方法談不上孰優孰劣,它們各有優點。若是在咱們把字符串中 work_up, call&apply::arga=b … 都看成特殊的單詞,咱們就須要第一種方法;若是咱們就是要中規中矩的單詞咱們可使用第二種方法。

若是第二個參數是func,介紹一個例子,字符串中單詞的首字母大寫:

let str = 'hello world';
str.replace(/\b\w+\b/g, (word) => word.substring(0,1).toUpperCase() + word.substring(1) );
複製代碼

字符串還有 lengthindexOfconcattoLowerCasetoUpperCase 等方法,這裏就不一一介紹了。

推薦

若是喜歡碼題的同窗可到www.hackerrank.com/domains/reg…這個網站去。

github.com/lvzhenbang/…

相關文章
相關標籤/搜索