【DailyENJS第6期】JavaScript正則表達(dá)式實(shí)用指南

DailyENJS 致力于翻譯優(yōu)秀的前端英文技術(shù)文章,為技術(shù)同學(xué)帶來(lái)更好的技術(shù)視野。

image

當(dāng)你第一次遇到正則表達(dá)式時(shí),它們看起來(lái)像是隨意的亂碼。雖然它們可能看起來(lái)不容易理解,但它們也非常有用。

事實(shí)上正確理解正則表達(dá)式將使你成為一個(gè)更加高效的程序員。為了完全理解正則表達(dá)式,您首先需要學(xué)習(xí)基礎(chǔ)知識(shí)。

什么是正則表達(dá)式

正則表達(dá)式是一種描述字符串?dāng)?shù)據(jù)中的模式的方法。它們構(gòu)成了自己的一種小語(yǔ)言,它是許多編程語(yǔ)言的一部分,如Javascript,Perl,Python,Php和Java。

正則表達(dá)式能夠幫助你去校驗(yàn)字符串,如電子郵件地址或密碼。

創(chuàng)建一個(gè)正則表達(dá)式

在Javascript中有兩種方式可以創(chuàng)建正則表達(dá)式。可以使用RegExp構(gòu)造函數(shù)創(chuàng)建,也可以使用正斜杠(/)來(lái)創(chuàng)建。

使用 RegExp 構(gòu)造函數(shù)

語(yǔ)法: new RegExp(pattern[, flags])

例子:

var regexConst = new RegExp('abc')

使用正則表達(dá)式字面量

語(yǔ)法: /pattern/flags

例子:

var regexLiteral = /abc/;

這里的 flags 是可選的,文章的后面將會(huì)解釋這些。

可能還有一些情況需要?jiǎng)討B(tài)創(chuàng)建正則表達(dá)式,在這種情況下,正則表達(dá)式字面量不起作用,因此您必須使用正則表達(dá)式構(gòu)造函數(shù)。

無(wú)論您選擇哪種方法,結(jié)果都是正則表達(dá)式對(duì)象,都有相同的方法和屬性。

由于正斜杠用于創(chuàng)建正則表達(dá)式,因此如果要將 / 用作正則表達(dá)式的一部分,則必須使用反斜杠(\)轉(zhuǎn)義正斜杠(/)。

正則表達(dá)式的方法

測(cè)試正則表達(dá)式主要有兩種方法。

RegExp.prototype.test()

這個(gè)方法用于測(cè)試是否已找到匹配項(xiàng)。它接受一個(gè)字符串作為參數(shù),并返回true或false:

例子:

var regex = /hello/;
var str = 'hello world';
var result = regex.test(str);
console.log(result);
// returns true

RegExp.prototype.exec()

這個(gè)方法返回包含所有匹配組的數(shù)組。它接受一個(gè)字符串作為參數(shù)。

例子:

var regex = /hello/;
var str = 'hello world';
var result = regex.exec(str);
console.log(result);
// returns [ 'hello', index: 0, input: 'hello world', groups: undefined ]
// 'hello' -> is the matched pattern.
// index: -> Is where the regular expression starts.
// input: -> Is the actual string passed.

我們將在下面使用test()方法。

簡(jiǎn)單的正則表達(dá)式匹配

它是最基本的模式,它簡(jiǎn)單地將文字文本與測(cè)試字符串相匹配。例如:

var regex = /hello/;
console.log(regex.test('hello world'));
// true

特殊字符

到目前為止,我們已經(jīng)創(chuàng)建了簡(jiǎn)單的正則表達(dá)式。現(xiàn)在,讓我們?cè)谔幚砀鼜?fù)雜的情況時(shí)充分利用正則表達(dá)式的全部功能。

例如,不是匹配特定的電子郵件地址,而是說(shuō)我們想要匹配許多電子郵件地址。這就是特殊字符發(fā)揮作用的地方。為了完全理解正則表達(dá)式,您必須記住特殊的符號(hào)和字符。

falgs

正則表達(dá)式有五個(gè)可選的flag或修飾符。讓我們討論兩個(gè)最重要的flag:

  • g:全局匹配;找到所有匹配,而不是在第一個(gè)匹配后停止

  • i:忽略大小寫(xiě)

您還可以在單??個(gè)正則表達(dá)式中組合修飾符。并且他們的順序?qū)Y(jié)果沒(méi)有任何影響。

接下來(lái)看看一些例子:

使用正則表達(dá)式字面量:

var regexGlobal = /abc/g;
console.log(regexGlobal.test('abc abc'));
// it will match all the occurence of 'abc', so it won't return
// after first match.
var regexInsensitive = /abc/i;
console.log(regexInsensitive.test('Abc'));
// returns true, because the case of string characters don't matter
// in case-insensitive search.

使用 RegExp 構(gòu)造函數(shù):

var regexGlobal = new RegExp('abc','g')
console.log(regexGlobal.test('abc abc'));
// it will match all the occurence of 'abc', so it won't return // after first match.
var regexInsensitive = new RegExp('abc','i')
console.log(regexInsensitive.test('Abc'));
// returns true, because the case of string characters don't matter // in case-insensitive search.

Character groups:

字符集[xyz]-字符集是一種在一個(gè)位置匹配不同字符的方法,它匹配括號(hào)內(nèi)的字符中字符串中的任何單個(gè)字符。例如:

var regex = /[bt]ear/;
console.log(regex.test('tear'));
// returns true
console.log(regex.test('bear'));
// return true
console.log(regex.test('fear'));
// return false

注: 除了插入符號(hào)(^)(在字符集中具有完全不同的含義)之外的所有特殊字符在字符集內(nèi)(中括號(hào)內(nèi))都會(huì)失去其特殊含義。

否定字符集(Negated character set [^xyz])—— 它匹配括號(hào)中未包含的任何內(nèi)容。例如:

var regex = /[^bt]ear/;
console.log(regex.test('tear'));
// returns false
console.log(regex.test('bear'));
// return false
console.log(regex.test('fear'));
// return true

范圍[a-z](Ranges[a-z]): 假設(shè)我們想要在一個(gè)位置匹配字母表中的所有字母,我們可以在括號(hào)內(nèi)寫(xiě)出所有字母,但有一種更簡(jiǎn)單的方法,那就是范圍。例如:[a-h]將匹配a到h的所有字母。范圍也可以是[0-9]之類(lèi)的數(shù)字或[A-Z]之類(lèi)的大寫(xiě)字母。

var regex = /[a-z]ear/;
console.log(regex.test('fear'));
// returns true
console.log(regex.test('tear'));
// returns true

元字符(Meta-characters) - 元字符是具有特殊含義的字符。有許多元字符,但我將在這里介紹最重要的元字符。

  • \d:匹配任何數(shù)字字符(與[0-9]相同)

  • \w: 匹配任何單詞字符。單詞字符是任何字母,數(shù)字和下劃線(xiàn)。(與[a-zA-Z0-9_]相同)即字母數(shù)字字符

  • \s: 匹配空白字符(空格,制表符等)

  • \t: 僅匹配制表符

  • \b: 在單詞的開(kāi)頭或結(jié)尾找到匹配項(xiàng)。也稱(chēng)為單詞邊界

  • .: 匹配除換行符之外的任何字符

  • \D: 匹配任何非數(shù)字字符(與[^ 0-9]相同)

  • \W: 匹配任何非單詞字符(與[^ a-zA-Z0-9_]相同)

  • \S: 匹配非空白字符

量詞: 量詞是在正則表達(dá)式中具有特殊含義的符號(hào)

  • +: 匹配前面的表達(dá)式1次或多次
var regex = /\d+/;
console.log(regex.test('8'));
// true
console.log(regex.test('88899'));
// true
console.log(regex.test('8888845'));
  • *: 匹配前面的表達(dá)式0次或更多次
var regex = /go*d/;
console.log(regex.test('gd'));
// true
console.log(regex.test('god'));
// true
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// true
  • ?: 匹配前面的表達(dá)式0或1次,即前面的模式是可選的
var regex = /goo?d/;
console.log(regex.test('god'));
// true
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// false
  • ^: 匹配字符串的開(kāi)頭。即插入符號(hào)(^)匹配字符串的開(kāi)頭。
var regex = /^g/;
console.log(regex.test('good'));
// true
console.log(regex.test('bad'));
// false
console.log(regex.test('tag'));
// false
  • : 匹配字符串的結(jié)尾,即美元()符號(hào)與字符串的結(jié)尾匹配。
var regex = /.com$/;
console.log(regex.test('test@testmail.com'));
// true
console.log(regex.test('test@testmail'));
// false
  • {N}: 完全匹配前面表達(dá)式N次
var regex = /go{2}d/;
console.log(regex.test('good'));
// true
console.log(regex.test('god'));
// false
  • {N,}: 匹配前面正則表達(dá)式至少N次
var regex = /go{2,}d/;
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// true
console.log(regex.test('gooood'));
// true
  • {N,M}: 匹配前面正則表達(dá)式至少N次且最多M次(其中M> N)
var regex = /go{1,2}d/;
console.log(regex.test('god'));
// true
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// false

Alternation X|Y: 匹配X或Y,例如:

var regex = /(green|red) apple/;
console.log(regex.test('green apple'));
// true
console.log(regex.test('red apple'));
// true
console.log(regex.test('blue apple'));
// false

注意 - 如果要將任何特殊字符用作表達(dá)式的一部分,例如,您希望匹配文字+或。,則必須使用反斜杠(\)對(duì)其進(jìn)行轉(zhuǎn)義。

例如:

var regex = /a+b/;  // This won't work
var regex = /a\+b/; // This will work
console.log(regex.test('a+b')); // true

高級(jí)

(x): 匹配x并記住這個(gè)匹配。這些被稱(chēng)為捕獲組。這也用于在正則表達(dá)式中創(chuàng)建子表達(dá)式。例如 :

var regex = /(foo)bar\1/;
console.log(regex.test('foobarfoo'));
// true
console.log(regex.test('foobar'));
// false

\1 記住并使用括號(hào)內(nèi)第一個(gè)子表達(dá)式匹配。

(?:x): 匹配x并且不記得匹配。這些被稱(chēng)為非捕獲組。這里 \1 不起作用,它將匹配文字 \1

var regex = /(?:foo)bar\1/;
console.log(regex.test('foobarfoo'));
// false
console.log(regex.test('foobar'));
// false
console.log(regex.test('foobar\1'));
// true

x(?=y): 僅當(dāng)x后跟y時(shí)才匹配x。也被稱(chēng)為正向先行斷言。例如:

var regex = /Red(?=Apple)/;
console.log(regex.test('RedApple'));
// true

在上面的示例中,僅當(dāng)Redis后跟Apple時(shí)才會(huì)進(jìn)行匹配。

正則表達(dá)式練習(xí)

讓我們練習(xí)一些我們上面學(xué)到的概念。

  • 匹配任何10個(gè)數(shù)字:
var regex = /^\d{10}$/;
console.log(regex.test('9995484545'));
// true

讓我們看一看發(fā)生了什么。

  1. 如果我們想強(qiáng)制匹配整個(gè)字符串,我們可以添加量詞^和。插入符號(hào)^匹配輸入字符串的開(kāi)頭,而美元符號(hào)匹配結(jié)尾。因此,如果字符串包含超過(guò)10位數(shù),則不匹配

  2. \d 匹配數(shù)字字符串

  3. {10} 匹配前一個(gè)表達(dá)式,在這種情況下 \d 恰好10次。因此,如果測(cè)試字符串包含少于或大于10位數(shù),則結(jié)果將為false。

  • 匹配日期格式DD-MM-YYYY或DD-MM-YY
var regex = /^(\d{1,2}-){2}\d{2}(\d{2})?$/;
console.log(regex.test('01-01-1990'));
// true
console.log(regex.test('01-01-90'));
// true
console.log(regex.test('01-01-190'));
// false

讓我們看一看發(fā)生了什么。

  1. 同樣,我們將整個(gè)正則表達(dá)式包裝在^和$中,以便匹配整個(gè)字符串。
  2. ( 開(kāi)始第一個(gè)子表達(dá)式
  3. \d{1,2} 匹配智商一個(gè)數(shù)字最多兩個(gè)數(shù)字
  4. - 匹配連字符
  5. ) 第一個(gè)子表達(dá)式的結(jié)尾
  6. {2} 精確匹配第一個(gè)子表達(dá)式2次
  7. \d{2} 精確匹配兩個(gè)數(shù)字字符
  8. (\d{2})? 精確匹配兩個(gè)數(shù)字并且是可選的

結(jié)論

正則表達(dá)式有時(shí)可能相當(dāng)復(fù)雜,但正確理解上述概念將有助于您輕松理解更復(fù)雜的正則表達(dá)式模式。
您可以在此處 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions 了解有關(guān)正則表達(dá)式的更多信息并可以在此處 https://www.hackerrank.com/domains/regex 練習(xí)。

最后照舊是一個(gè)廣告貼,最近新開(kāi)了一個(gè)分享技術(shù)的公眾號(hào),歡迎大家關(guān)注??(目前關(guān)注人數(shù)可憐??)

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,688評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,654評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,456評(píng)論 6 406
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,955評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,195評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,608評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,802評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,048評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,422評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,673評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,424評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,762評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容

  • 正則表達(dá)式到底是什么東西?字符是計(jì)算機(jī)軟件處理文字時(shí)最基本的單位,可能是字母,數(shù)字,標(biāo)點(diǎn)符號(hào),空格,換行符,漢字等...
    獅子挽歌閱讀 2,160評(píng)論 0 9
  • 9.19--9.23 第7章 正則表達(dá)式 正則表達(dá)式是一個(gè)拆分字符串并查詢(xún)相關(guān)信息的過(guò)程。 推薦練習(xí)網(wǎng)站: js ...
    如201608閱讀 1,047評(píng)論 0 4
  • 幾個(gè)正則表達(dá)式編輯器 Debuggex :https://www.debuggex.com/ PyRegex:ht...
  • 古書(shū)有言:“天地之氣,暖則生,寒則殺,性氣清冷者,受享亦涼薄,唯和氣熱心之人,其福亦厚,其澤亦長(zhǎng)。”看清一個(gè)人的人...
    鑫哥獨(dú)特閱讀 243評(píng)論 0 2
  • 我們學(xué)校開(kāi)了一門(mén)課,叫做:“國(guó)故新知-科學(xué)走進(jìn)人文”。選課的時(shí)候,我看到里面內(nèi)容包絡(luò)萬(wàn)象,既有國(guó)學(xué),又有科學(xué)。早些...
    落葉之上閱讀 333評(píng)論 3 2