成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

正則表達(dá)式小記

DevTTL / 2854人閱讀

摘要:什么是正則表達(dá)式正則表達(dá)式是用于匹配字符串中字符組合的模式。在中,正則表達(dá)式也是對(duì)象。正則表達(dá)式存在于大部分的編程語(yǔ)言,就算是在寫時(shí)也會(huì)不經(jīng)意的用到正則。第二個(gè)參數(shù)卻是可以傳入一個(gè)字符串,也可以傳入一個(gè)回調(diào)函數(shù)。

什么是正則表達(dá)式
正則表達(dá)式是用于匹配字符串中字符組合的模式。在 JavaScript中,正則表達(dá)式也是對(duì)象。
這些模式被用于 RegExpexectest 方法, 以及 Stringmatch、replacesearchsplit 方法。

正則表達(dá)式存在于大部分的編程語(yǔ)言,就算是在寫shell時(shí)也會(huì)不經(jīng)意的用到正則。
比如大家最喜歡的rm -rf ./*,這里邊的*就是正則的通配符,匹配任意字符。

JavaScript也有正則表達(dá)式的實(shí)現(xiàn),差不多就長(zhǎng)這個(gè)樣子:/d/(匹配一個(gè)數(shù)字)。
個(gè)人認(rèn)為正則所用到的地方還是很多的,比如模版字符的替換、解析URL,表單驗(yàn)證 等等一系列。
如果在Node.js中用處就更為多,比如請(qǐng)求頭的解析、文件內(nèi)容的批量替換以及寫爬蟲時(shí)候一定會(huì)遇到的解析HTML標(biāo)簽。

正則表達(dá)式在JavaScript中的實(shí)現(xiàn) JavaScript中的語(yǔ)法

贅述那些特殊字符的作用并沒有什么意義,浪費(fèi)時(shí)間。
推薦MDN的文檔:基礎(chǔ)的正則表達(dá)式特殊字符

關(guān)于正則表達(dá)式,個(gè)人認(rèn)為以下幾個(gè)比較重要:

貪婪模式與非貪婪模式

P.S. 關(guān)于貪婪模式非貪婪模式,發(fā)現(xiàn)有些地方會(huì)拿這樣的例子:

/.+/ // 貪婪模式
/.+?/ // 非貪婪模式

僅僅拿這樣簡(jiǎn)單的例子來(lái)說(shuō)的話,有點(diǎn)兒扯淡

// 假設(shè)有這樣的一個(gè)字符串
let html = "

text1text2

" // 現(xiàn)在我們要取出第一個(gè)`span`中的文本,于是我們寫了這樣的正則 html.match(/(.+)/) // 卻發(fā)現(xiàn)匹配到的竟然是 text1text2 // 這是因?yàn)?我們括號(hào)中寫的是 `(.+)` .為匹配任意字符, +則表示匹配一次以上。 // 當(dāng)規(guī)則匹配到了`text1`的時(shí)候,還會(huì)繼續(xù)查找下一個(gè),發(fā)現(xiàn)`<`也命中了`.`這個(gè)規(guī)則 // 于是就持續(xù)的往后找,知道找到最后一個(gè)span,結(jié)束本次匹配。 // 但是當(dāng)我們把正則修改成這樣以后: html.match(/(.+?)/) // 這次就能匹配到我們想要的結(jié)果了 // `?`的作為是,匹配`0~1`次規(guī)則 // 但是如果跟在`*`、`+`之類的表示數(shù)量的特殊字符后,含義就會(huì)變?yōu)槠ヅ浔M量少的字符。 // 當(dāng)正則匹配到了text1后,判斷后邊的命中了規(guī)則,就直接返回結(jié)果,不會(huì)往后繼續(xù)匹配。

簡(jiǎn)單來(lái)說(shuō)就是:

貪婪模式,能拿多少拿多少

非貪婪模式,能拿多拿多少

捕獲組

/123(d+)0/ 括號(hào)中的被稱之為捕獲組。

捕獲組有很多的作用,比如處理一些日期格式的轉(zhuǎn)換。

let date = "2017-11-21"

date.replace(/^(d{4})-(d{2})-(d{2})$/, "$2/$3/$1")

又或者可以直接寫在正則表達(dá)式中作為前邊重復(fù)項(xiàng)的匹配。

let template = "hello helloworl"
template.match(/(w+) 1/) // => hello hello

// 我們可以用它來(lái)匹配出month和day數(shù)字相同的數(shù)據(jù)
let dateList = `
2017-10-10
2017-11-12
2017-12-12
`

dateList.match(/^d{4}-(d{2})-(1)/gm) // => ["2017-10-10", "2017-12-12"]
非捕獲組

我們讀取了一個(gè)文本文件,里邊是一個(gè)名單列表
我們想要取出所有Stark的名字(但是并不想要姓氏,因?yàn)槎冀蠸tark),我們就可以寫這樣的正則:

let nameList = `
Brandon Stark
Sansa Stark
John Snow
`

nameList.match(/^w+(?=s?Stark)/gm) // => ["Brandon", "Sansa"]

上邊的(?=)就是非捕獲組,意思就是規(guī)則會(huì)被命中,但是在結(jié)果中不會(huì)包含它。

比如我們想實(shí)現(xiàn)一個(gè)比較常用的功能,給數(shù)組添加千分位:

function numberWithCommas (x = 0) {
  return x.toString().replace(/B(?=(d{3})+(?!d))/g, ",")
}

numberWithCommas(123) // => 123
numberWithCommas(1234) // => 1,234

B代表匹配一個(gè)非單詞邊界,也就是說(shuō),實(shí)際他并不會(huì)替換掉任何的元素。
其次,后邊的非捕獲組這么定義:存在三的倍數(shù)個(gè)數(shù)字(3、6、9),并且這些數(shù)字后邊沒有再跟著其他的數(shù)字。
因?yàn)樵诜遣东@組中使用的是(d{3})+,貪婪模式,所以就會(huì)盡可能多的去匹配。
如果傳入字符串1234567,則第一次匹配的位置在12之間,第二次匹配的位置在45之間。
獲得的最終字符串就是1,234,567

如何使用正則表達(dá)式 RegExp對(duì)象

創(chuàng)建RegExp對(duì)象有兩種方式:

直接字面量的聲明:/d/g

通過(guò)構(gòu)造函數(shù)進(jìn)行創(chuàng)建:new RegExp("d", "g")

RegExp對(duì)象提供了兩個(gè)方法:

exec

方法執(zhí)行傳入一個(gè)字符串,然后對(duì)該字符串進(jìn)行匹配,如果匹配失敗則直接返回null
如果匹配成功則會(huì)返回一個(gè)數(shù)組:

let reg = /([a-z])d+/
let str = "a233"
let result = reg.exec(str) // => ["a233", "a", ...]

P.S. 如果正則表達(dá)式有g標(biāo)識(shí),在每次執(zhí)行完exec后,該正則對(duì)象的lastIndex值就會(huì)被改變,該值表示下次匹配的開始下標(biāo)

let reg = /([a-z])d+/g
let str = "a233"
reg.exec(str) // => ["a233", "a", ...]
// reg.lastIndex = 4
reg.exec(str) // => null
test

方法用來(lái)檢查正則是否能成功匹配該字符串

let reg = /^Hello/

reg.test("Hello World") // => true
reg.test("Say Hello") // => false

test方法一般來(lái)說(shuō)多用在檢索或者過(guò)濾的地方。
比如我們做一些篩選filter的操作,用test就是一個(gè)很好的選擇。

// 篩選出所有名字為 Niko的數(shù)據(jù)
let data = [{ name: "Niko Bellic" }, { name: "Roman Bellic"}]

data.filter(({name}) => /^Niko/.test(name)) // => [{ name: "Niko Bellic" }]
String對(duì)象
除了RegExp對(duì)象實(shí)現(xiàn)的一些方法外,String同樣提供了一套方法供大家來(lái)使用。
search

傳入一個(gè)正則表達(dá)式,并使用該表達(dá)式進(jìn)行匹配;
如果匹配失敗,則會(huì)返回-1
如果匹配成功,則會(huì)返回匹配開始的下標(biāo)。
可以理解為是一個(gè)正則版的indexOf

"Hi Niko".search(/Niko/) // => 3
"Hi Niko".search(/Roman/) // => -1

// 如果傳入的參數(shù)為一個(gè)字符串,則會(huì)將其轉(zhuǎn)換為`RegExp`對(duì)象
"Hello".search("llo") // => 2
split

split方法應(yīng)該是比較常用的,用得最多的估計(jì)就是[].split(",")了。。

然而這個(gè)參數(shù)也是可以塞進(jìn)去一個(gè)正則表達(dá)式的。

"1,2|3".split(/,||/) // => [1, 2, 3]

// 比如我們要將一個(gè)日期時(shí)間字符串進(jìn)行分割
let date = "2017-11-21 23:40:56"

date.split(/-|s|:/)

// 又或者我們有這么一個(gè)字符串,要將它正確的分割
let arr = "1,2,3,4,[5,6,7]"

arr.split(",") // => ["1", "2", "3", "4", "[5", "6", "7]"] 這個(gè)結(jié)果肯定是不對(duì)的。

// 所以我們可以這么寫
arr.split(/,(?![,d]+])/) // => ["1", "2", "3", "4", "[5,6,7]"]

該條規(guī)則會(huì)匹配,,但是,后邊還有一個(gè)限定條件,那就是絕對(duì)不能出現(xiàn)數(shù)字+,的組合并且以一個(gè)]結(jié)尾。
這樣就會(huì)使[4,5,6]里邊的,不被匹配到。

match

match方法用來(lái)檢索字符串,并返回匹配的結(jié)果。

如果正則沒有添加g標(biāo)識(shí)的話,返回值與exec類似。
但是如果添加了g標(biāo)識(shí),則會(huì)返回一個(gè)數(shù)組,數(shù)組的item為滿足匹配條件的子串。
這將會(huì)無(wú)視掉所有的捕獲組。
拿上邊的那個(gè)解析HTML來(lái)說(shuō)

let html = "

text1text2

" html.match(/(.+?)/g) // => ["text1", "text2"]
replace

replace應(yīng)該是與正則有關(guān)的應(yīng)用最多的一個(gè)函數(shù)。
最簡(jiǎn)單的模版引擎可以基于replace來(lái)做。
日期格式轉(zhuǎn)換也可以通過(guò)replace來(lái)做。
甚至match的功能也可以通過(guò)replace來(lái)實(shí)現(xiàn)(雖說(shuō)代碼會(huì)看起來(lái)很丑)

replace接收兩個(gè)參數(shù)
replace(str|regexp, newStr|callback)

第一個(gè)參數(shù)可以是一個(gè)字符串 也可以是一個(gè)正則表達(dá)式,轉(zhuǎn)換規(guī)則同上幾個(gè)方法。
第二個(gè)參數(shù)卻是可以傳入一個(gè)字符串,也可以傳入一個(gè)回調(diào)函數(shù)。

當(dāng)傳入字符串時(shí),會(huì)將正則所匹配到的字串替換為該字符串。
當(dāng)傳入回調(diào)函數(shù)時(shí),則會(huì)在匹配到子串時(shí)調(diào)用該回調(diào),回調(diào)函數(shù)的返回值會(huì)替換被匹配到的子串。

"Hi: Jhon".replace(/Hi:s(w+)/g, "Hi: $1 Snow") // => Hi: Jhon Snow

"price: 1".replace(/price:s(d)/g, (/* 匹配的完整串 */str, /* 捕獲組 */ $1) => `price: ${$1 *= 10}`) // => price: 10
一些全新的特性
前段時(shí)間看了下ECMAScript 2018的一些草案,發(fā)現(xiàn)有些Stage 3的草案,其中有提到RegExp相關(guān)的,并在chrome上試驗(yàn)了一下,發(fā)現(xiàn)已經(jīng)可以使用了。
Lookbehind assertions(應(yīng)該可以叫做回溯引用吧)
同樣也是一個(gè)非捕獲組的語(yǔ)法定義

語(yǔ)法定義:

let reg = /(?<=Pre)w/

reg.test("Prefixer") // => true
reg.test("Prfixer") // => false

設(shè)置匹配串前邊必須滿足的一些條件,與(?=)正好相反,一前一后。
這個(gè)結(jié)合著(?=)使用簡(jiǎn)直是神器,還是說(shuō)解析HTML的那個(gè)問題。
現(xiàn)在有了(?<=)以后,我們甚至可以直接通過(guò)一個(gè)match函數(shù)拿到HTML元素中的文本值了。

let html = "

text1text2

" html.match(/(?<=)(.+?)(?=)/g) // => ["text1", "text2"]
Named capture groups(命名捕獲組)

我們知道,()標(biāo)識(shí)這一個(gè)捕獲組,然后用的時(shí)候就是通過(guò)1或者$1來(lái)使用。
這次草案中提到的命名捕獲組,就是可以讓你對(duì)()進(jìn)行命名,在使用時(shí)候可以用接近變量的用法來(lái)調(diào)用。

語(yǔ)法定義:

let reg = /(?d{4})-(?d{2})-(?d{2})/

"2017-11-21".match(reg)

match的返回值中,我們會(huì)找到一個(gè)groupskey
里邊存儲(chǔ)著所有的命名捕獲組。

在replace中的用法
let reg = /(?d{4})-(?d{2})-(?d{2})/
"2017-11-21".replace(reg, "$/$/$") // => 21/11/2017
表達(dá)式中的反向引用
let reg = /d{4}-(?d{2})-k/
reg.test("2017-11-11") // => true
reg.test("2017-11-21") // => false
參考資料

MDN-正則表達(dá)式

RegExp named capture groups

RegExp lookbehind assertions

在線正則匹配規(guī)則

個(gè)人GitHub:https://github.com/jiasm

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93719.html

相關(guān)文章

  • Python小記(一):import和from。。。import區(qū)別?

    摘要:而當(dāng)我們時(shí)這個(gè)是一個(gè)類我們稱呼它為函數(shù)。后兩者是常量用于忽略換行符和大小寫。這就會(huì)導(dǎo)致很多難以覺察的潛在。結(jié)論無(wú)論是使用還是第一個(gè)要求是代碼能夠正常運(yùn)行其次根據(jù)代碼維護(hù)性團(tuán)隊(duì)編碼風(fēng)格來(lái)確定選擇哪一種方案。 ...

    番茄西紅柿 評(píng)論0 收藏2637
  • webpack替代fekit的折騰小記

    摘要:添加依賴到如何使用依賴當(dāng)你再興建一個(gè)文件的時(shí)候,就不需要一個(gè)個(gè)插件安裝了,將文件復(fù)制到當(dāng)前文件下,并輸入,即通過(guò)里的依賴關(guān)系,自動(dòng)把依賴安裝好了。第四步新建配置文件默認(rèn)的配置文件在項(xiàng)目目錄下為。 WilsonLius blog 首發(fā)地址 前言 早就想嘗試webpack的,卻一直沒有時(shí)間,恰逢周末,又時(shí)值最近在公司實(shí)習(xí)的時(shí)候嘗到用fekit做模塊化的構(gòu)建工具的爽。所以就開始以公司的項(xiàng)目結(jié)...

    curried 評(píng)論0 收藏0
  • JavaScript & jQuery 常用方法小記

    摘要:函數(shù)節(jié)流用途如調(diào)整瀏覽器大小,或者用戶輸入信息,導(dǎo)致反復(fù)提交接口調(diào)用方法判斷手機(jī)端訪問獲取地址欄參數(shù)返回頂部當(dāng)滾動(dòng)條的位置處于距頂部像素以下時(shí),跳轉(zhuǎn)鏈接出現(xiàn),否則消失當(dāng)點(diǎn)擊跳轉(zhuǎn)鏈接后,回到頁(yè)面頂部位置正則檢測(cè)手機(jī)號(hào)郵箱 1.JavaScript 函數(shù)節(jié)流用途:如調(diào)整瀏覽器大小,或者用戶輸入信息,導(dǎo)致反復(fù)提交接口 function throttle(method,context) { ...

    codeGoogle 評(píng)論0 收藏0
  • gulp組織小型項(xiàng)目小記

    摘要:目前正在開發(fā)一個(gè)系統(tǒng),對(duì)于前端模塊化與打包這塊出現(xiàn)了一些選擇。采用模塊化及打包由于項(xiàng)目比較小,稍微了解后,覺得沒必要采用。組件化,目前比較流行的如等。項(xiàng)目較小需要交互更新頁(yè)面的并不多,沒有采用。 目前正在開發(fā)一個(gè)python markdown wiki系統(tǒng),對(duì)于前端模塊化與打包這塊出現(xiàn)了一些選擇。1、采用webpack模塊化及打包由于項(xiàng)目比較小,稍微了解后,覺得沒必要采用webpack...

    2json 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<