熟悉個人朋友可能會知道,我一貫是不寫熱點的。爲何不寫呢?是由於我不關注熱點嗎?其實也不是。有些事件我仍是很關注的,也確實有很多想法和觀點。 但我一直奉行一個原則,就是:要作有生命力的內容。javascript
對於前端工程師來講, 正則表達式也許是javascript語言中最晦澀難懂的, 可是也每每是最簡潔的.工做中遇到的不少問題,諸如搜索,查找, 高亮關鍵字等均可以使用正則輕鬆解決,因此有句話說的好:css
正則用的好, 加班遠離我.html
今天筆者就覆盤一下javascript正則表達式的一些使用技巧和高級API, 並經過幾個實際的案例,來展示正則表達式的魅力.若是你們以爲正則表達式理解起來很麻煩,也可使用以下在線網站, 只須要輸入你的正則表達式, 它就能以圖形的方式將你的正則展現出來: 前端
對於正則的基本用法筆者這裏就不總結了,這裏重點介紹一些比較有用且難懂的知識點.在最後筆者會寫10個經典的正則案例, 供你們學習參考, 或者在工做中直接使用. vue
以上幾點應用筆者在下文中會寫幾個例子來說解.模式匹配主要用來匹配某一類字符串並記住匹配項.java
案例:node
let str = 'xuxi is xuxi is'
let reg = /(xuxi) (is) \1 \2/g
reg.test(str) // true (1)
str.replace(reg, '$1 $2') // xuxi is (2)
複製代碼
解釋: 其中括號被稱爲捕獲括號, 模式中的 \1 和 \2 表示第一個和第二個被捕獲括號匹配的子字符串,即 xuxi 和 is,匹配了原字符串中的後兩個單詞, 所以(1)中運行的結果爲true. 當咱們在字符串中使用replace時, 咱們可使用$1, $2這樣的方式獲取第n個匹配項,並用來替換字符串. 如(2)中的運行結果.react
主要用來匹配某一類字符串但不記住匹配項.webpack
案例:css3
let str = 'xuxixuxi'
let reg = /(?:xuxi){1,2}/g
reg.test(str) // true (1)
複製代碼
解釋: 其中(?:)被稱爲非捕獲括號, 咱們可使用它匹配一組字符可是並不記住該字符,通常用來判斷某類字符是否存在於某字符串中.
先行斷言: 匹配'x'僅僅當'x'後面跟着'y'.
案例:
let str = '王者融化'
let reg = /王(?=者)/
reg.test(str) // true (1)
複製代碼
解釋: /王(?=者)/會匹配到"王"僅當它後面跟着"者".可是"者"不屬於匹配結果的一部分.
後行斷言: 匹配'x'僅當'x'前面是'y'.
案例:
let str = 'xuxiA'
let reg = /(?<=xuxi)A/
reg.test(str) // true (1)
複製代碼
解釋: /(?<=xuxi)A/會匹配到A僅當它前面爲xuxi.可是xuxi不屬於匹配結果的一部分.
正向否認查找: 僅僅當'x'後面不跟着'y'時匹配'x'.
案例:
let str = '3.1415'
let reg = /\d+(?!\.)/
reg.exec(str) // [1415] (1)
複製代碼
解釋: 其中/\d+(?!.)/匹配一個或多個數字,當且僅當它後面沒有小數點時, 因此(1)中執行後會匹配到1415而不是3.1415
反向否認查找: 僅僅當'x'前面不是'y'時匹配'x'.
案例:
let str = '3.1415'
let reg = /(?<!\.)\d+/
reg.exec(str) // [3] (1)
複製代碼
解釋: /(?<!.)\d+/匹配一個數字,當且僅當前面字符不是.時,此時將匹配3.
[xyz]: 一個字符集合。匹配方括號中的任意字符,包括轉義序列。你可使用破折號(-)來指定一個字符範圍。
[^xyz]: 一個反向字符集。也就是說,它匹配任何沒有包含在方括號中的字符。你可使用破折號(-)來指定一個字符範圍。任何普通字符在這裏都是起做用的
案例:
let str = 'abcd'
let reg1 = /[a-c]+/
let reg2 = /[^d]$/
reg1.test(str) // true (1)
reg2.test(str) // true (2)
複製代碼
解釋: (1)中將返回true由於字符串中包含a-c中的字符, (2)中獎返回false, 由於字符串結尾爲d, 但正則reg2須要匹配結尾不爲d的字符串.
\b 匹配一個詞的邊界。一個詞的邊界就是一個詞不被另一個「字」字符跟隨的位置或者前面跟其餘「字」字符的位置,例如在字母和空格之間。注意,匹配中不包括匹配的字邊界。換句話說,一個匹配的詞的邊界的內容的長度是0。
\B 匹配一個非單詞邊界。匹配以下幾種狀況: (1)字符串第一個字符爲非「字」字符 (2)字符串最後一個字符爲非「字」字符 (3)兩個單詞字符之間 (4)兩個非單詞字符之間 (5)空字符串
案例:
let str = 'xuxi'
let reg1 = /xi\b/
let reg2 = /xu\B/
reg1.exec(str) // [xi] (1)
reg2.exec(str) // [xu] (2)
複製代碼
解釋: (1)中匹配到了單詞邊界,即xi, 爲該字符串的末尾.(2)中應爲xu爲非單詞邊界,因此會被其匹配到.
\s: 匹配一個空白字符,包括空格、製表符、換頁符和換行符.
\S: 匹配一個非空白字符
案例:
let str = 'xuxi is'
let reg1 = /.*\s/g
let reg2 = /\S\w*/g
reg1.exec(str) // [xuxi] (1)
reg2.exec(str) // [xuxi] (2)
複製代碼
解釋: (1)和(2)中執行以後都將匹配xuxi, 一個是空白字符以前的匹配, 一個是非空白字符的匹配.
\w: 匹配一個單字字符(字母、數字或者下劃線)。等價於 [A-Za-z0-9_]。
因爲以上2種模式比較簡單,這裏就不一一介紹了.\W: 匹配一個非單字字符。等價於 [^A-Za-z0-9_]
接下來筆者將總結幾個使用正則的實際應用,供你們學習和參考.
function trimTag(tagName, htmlStr) {
let reg = new RegExp(`<${tagName}(\\s.*)*>(\\n|.)*<\\/${tagName}>`, "g")
return htmlStr.replace(reg, '')
}
複製代碼
// 短橫線轉駝峯命名, flag = 0爲小駝峯, 1爲大駝峯
function toCamelCase(str, flag = 0) {
if(flag) {
return str[0].toUpperCase() + str.slice(1).replace(/-(\w)/g, ($0, $1) => $1.toUpperCase())
}else {
return str.replace(/-(\w)/g, ($0, $1) => $1.toUpperCase())
}
}
複製代碼
關於實現一個模板引擎, 實現中用到了大量的正則,建議感興趣的能夠直接看實現一個簡單的模板引擎.
function trimAll(str) {
return str.replace(/\s*/g,"")
}
複製代碼
function numCheck(str, specialNum) {
if(str.indexOf(',') > -1) {
return str.splite(',').every(item=>this.numCheck(item));
} else {
return str.split(specialNum).length === 2;
}
}
複製代碼
// 去除url參數字符串中值爲空的字段
const trimParmas = (parmaStr:string = '') => {
return parmaStr.replace(/((\w*?)=&|(&\w*?=)$)/g, '')
}
複製代碼
function unParams(params = '?a=1&b=2&c=3') {
let obj = {}
params && params.replace(/((\w*)=([\.a-z0-9A-Z]*)?)?/g, (m,a,b,c) => {
if(b || c) obj[b] = c
})
return obj
}
複製代碼
/** * 計算字符串字節數 * @param str * @desc 一箇中文佔2個字節, 一個英文佔一個字節 */
function computeStringByte(str) {
let size = 0,
strArr = str.split(''),
reg = /[\u4e00-\u9fa5]/ // 判斷是否爲中文
for(let i = strArr.length; i--; i>=0) {
if(reg.test(strArr[i])) {
size+= 2
}else {
size += 1
}
}
return size
}
複製代碼
function hasCn(str) {
let reg = /[\u4e00-\u9fa5]/g
return reg.test(str)
}
複製代碼
function searchLink(keyword) {
// 模擬後端返回數據
let list = ['abc', 'ab', 'a', 'bcd', 'edf', 'abd'];
let reg = new RegExp(keyword, 'i');
return list.filter(item => reg.test(item))
}
複製代碼
若是想學習更多H5遊戲, webpack,node,gulp,css3,javascript,nodeJS,canvas數據可視化等前端知識和實戰,歡迎在公號《趣談前端》加入咱們的技術羣一塊兒學習討論,共同探索前端的邊界。