知識學到本身手裏的纔是本身的,若是複製,粘貼別人的對本身幫助並不大,它只能幫本身解決一時的問題(有時還要花費本身大量的時間來查找),而不能從根本上解決問題。git
就好像前段時間個人的大學同窗問了我一個正則問題,如何驗證用戶輸入的密碼必須包含字符、數字、特殊符號,他說在百度上找了大量的正則示例都不能解決問題,我就問而後呢,他給我說我問你,我當時就無語了,我當時由於正在作項目,一時沒想出來,我跟他說你沒試着換個思路,暫時沒有找到用一個正則解決這個問題的你就不會試着分別對字符,數字,特殊字符單獨判斷,而後進行與運算不就好了,再者說了從用戶體驗上用一個正則判斷後給出一個結果,用戶體驗也很差,應該針對用戶輸入不一樣的狀況給出不一樣的提示信息,若是密碼的組成沒有數字,就提示沒有數字,若是沒有字符就提示沒有字符...... , 若是以此類推以爲判斷過多,你能夠再簡化處理,如只有密碼組成包含兩種,就提示缺乏的一種,若是密碼組成只包含一種,就提示密碼應該有字符、數字、特殊符號組成。github
這無形中給我上了生動的一課,正則不只其餘人忽視了,我也忽視了,有所欠缺。因此儘管最近在努力拿下設計模式這個高地,仍是決定抽出一部分時間梳理一下本身的正則知識的掌握。正則表達式
下面只列出經常使用的字符,以及我我的對它們的分類。設計模式
()
: 括號內的表達式表示一個分組[]
: 方括號內的表達式表示一個集合^
: 若是出如今集合([]
)中表示取反,不然是是定位符,從字符串的前邊界開始匹配|
:它表示或的意思,就是起到或運算的做用?:
: 它的做用是放在第一個選項前來消除相關匹配會被緩存這種反作用^
: 上面已經說了它定義正則運算的前邊界$
: 它定義了正則運算的後邊界\b
: 匹配一個字符的邊界(也便是字符和空白字符的分界)\d
: 表明數字,而 \D
,非數字\w
: 表明單詞,而 \W
,非單詞\s
: 表明空白符,而 \D
,非空白字符.
: 任意字符它是用來指定匹配結果的長度或次數。數組
匹配該符號前面的表達式緩存
+
: 一次或更屢次微信
*
:零次或屢次微信開發
?
: 零次或一次app
{}
: 匹配次數與話括號內的值有關。dom
若是 {n}
,就是匹配n次; 若是 {n,}
,就是匹配至少n次; 若是 {n,m}
,就是匹配n到m之間的任意次數。
正則用在字符串的處理上,能夠減小咱們的js代碼的書寫量,優化咱們的代碼,同時對於咱們學習別人源碼中複雜的正則已有幫助。
下面是一張來自知乎關於你是如何學會正則表達式的?問題的一張圖,掌握這張圖的正則,大概你就能解決你所面臨的大部分問題。
/^\s*[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*\s*$/
複製代碼
下面推薦幾款可視化的正則編輯器。
regexper (這是我最先接觸到的一款)
Regulex (這一款是我如今常用的)
RegExr (這一款功能很強大,對於學習正則頗有幫助,若是學習正則的話強烈推薦)
正則是一個很強大的字符串查詢和替換的方法。
之前咱們有時侯老是在想將字符串轉換爲數字數組,利用數組的方法來處理字符,可是要知道字符串就是咱們在生活和工做中常見的形式,數字、數組、Boolean類型的相對較少,尤爲是最近在作微信開發時發現正則很重要,我同窗的例子,只是給了我一個深刻學習和研究的動力,這只是個人初步總結,之後有必要的話還會增強。
在JavaScript中咱們使用 RegExp
來建立一個對象來實現正則表達式。
一個正則有兩部分組成:正則主體和修飾符。
形式以下:
regExp = new RegExp('pattern', 'flag');
// 或者
regExp = /pattern/gmi
複製代碼
正則的修飾符一共有5種,分別爲:
g
: 全部匹配的狀況,若是沒有它,只一種匹配狀況i
: 忽略字符的大小寫m
: 支持多行u
: 支持 Unicodey
: 嚴格模式(返回指定位置後的匹配結果)test
方法返回值爲true/false
let str = "Hello world!";
let regexp = /hello/i;
console.log(regexp.test(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
在String的方法中使用正則,能夠輕鬆的解決咱們平常開發中的問題。
若是有匹配結果,返回第一個匹配結果的首字符位置;不然,返回 `-1`。
let str = "Hello world!";
regexp = /o/i;
str.search(regexp); // 4
複製代碼
注;search
只能返回第一次匹配的結果,而不能返回其餘匹配結果
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
。
將給定的字符串按單詞爲單位進行分割,返回一個由單詞組成的數組。
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()
,效果以下:
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
,::arg
,a=b
… 都看成特殊的單詞,咱們就須要第一種方法;若是咱們就是要中規中矩的單詞咱們可使用第二種方法。
若是第二個參數是func,介紹一個例子,字符串中單詞的首字母大寫:
let str = 'hello world';
str.replace(/\b\w+\b/g, (word) => word.substring(0,1).toUpperCase() + word.substring(1) );
複製代碼
字符串還有 length
,indexOf
,concat
,toLowerCase
,toUpperCase
等方法,這裏就不一一介紹了。
若是喜歡碼題的同窗可到www.hackerrank.com/domains/reg…這個網站去。