Javascript 量詞 +, *, ? 和 {n}

2023-02-17 11:01 更新

假設(shè)我們有一個(gè)像這樣 ?+7(903)-123-45-67? 的字符串,并想要找到其中所有數(shù)字。但與之前不同的是,我們對(duì)單個(gè)數(shù)字不感興趣,只對(duì)全數(shù)感興趣:?7, 903, 123, 45, 67?。

數(shù)字是一個(gè)或多個(gè)數(shù)字 \d 的序列。為了標(biāo)記我們需要的數(shù)量,我們需要加一個(gè) 量詞

數(shù)量 {n}

最簡(jiǎn)單的量詞便是大括號(hào)中的數(shù)字:{n}。

在一個(gè)字符(或一個(gè)字符類,或 [...] 等)后附加一個(gè)量詞,用來(lái)指出我們具體需要的數(shù)量。

它有一些高級(jí)的形式,讓我們看一些例子:

確切的位數(shù):{5}

\d{5} 表示 5 位數(shù),與 \d\d\d\d\d 相同。

下面這個(gè)例子查找一個(gè)五位數(shù)的數(shù)字:

alert( "I'm 12345 years old".match(/\d{5}/) ); //  "12345"

我們可以添加 \b 來(lái)排除位數(shù)更多的數(shù)字:\b\d{5}\b。

范圍:{3,5},匹配 3-5 個(gè)

要查找 3-5 位的數(shù)字,我們可以將限制寫(xiě)在花括號(hào)中:\d{3,5}

alert( "I'm not 12, but 1234 years old".match(/\d{3,5}/) ); // "1234"

我們可以省略上限。

那么正則表達(dá)式 \d{3,} 就會(huì)查找位數(shù)大于等于 3 的數(shù)字:

alert( "I'm not 12, but 345678 years old".match(/\d{3,}/) ); // "345678"

讓我們回到字符串 +7(903)-123-45-67。

我們?nèi)绻枰粋€(gè)及以上的數(shù)字,就使用 \d{1,}

let str = "+7(903)-123-45-67";

let numbers = str.match(/\d{1,}/g);

alert(numbers); // 7,903,123,45,67

縮寫(xiě)

大多數(shù)常用的量詞都有簡(jiǎn)寫(xiě)形式:

?+?

代表“一個(gè)或多個(gè)”,與 {1,} 相同。

例如,\d+ 用來(lái)查找所有數(shù)字:

let str = "+7(903)-123-45-67";

alert( str.match(/\d+/g) ); // 7,903,123,45,67

???

代表“零個(gè)或一個(gè)”,與 {0,1} 相同。換句話說(shuō),它使得符號(hào)變得可選。

例如,模式 ou?r 查找 o,后跟零個(gè)或一個(gè) u,然后是 r。

所以 colou?r 會(huì)找到 color 和 colour

let str = "Should I write color or colour?";

alert( str.match(/colou?r/g) ); // color, colour

?*?

代表“零個(gè)及以上”,與 {0,} 相同。也就是說(shuō),字符可以出現(xiàn)任何次數(shù)或者不出現(xiàn)。

例如,\d0* 查找一個(gè)數(shù)字后面跟著任意數(shù)量的零(可能有很多或沒(méi)有)的數(shù)字:

alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1

將其與 +(一個(gè)或更多)做比較:

alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 沒(méi)有被匹配出來(lái),因?yàn)?0+ 要求至少有一個(gè) 0

更多示例

量詞是很常用的。它們是構(gòu)成復(fù)雜正則表達(dá)式的主要“模塊”,所以讓我們看更多示例。

小數(shù)的正則表達(dá)式(帶浮點(diǎn)的數(shù)字):\d+\.\d+

實(shí)現(xiàn):

alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345

”沒(méi)有特性(attribute)的打開(kāi)的 HTML 標(biāo)簽(例如 <span> 或 <p>)“的正則表達(dá)式。

  1. 最簡(jiǎn)單的:/<[a-z]+>/i

    alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>

    正則表達(dá)式查找的匹配項(xiàng)是字符 '<' 后跟一個(gè)或多個(gè)拉丁字母,然后是 '>'。

  2. 進(jìn)階版:/<[a-z][a-z0-9]*>/i

    根據(jù)標(biāo)準(zhǔn),HTML 標(biāo)簽名稱可以在除了第一個(gè)位置之外的任何位置有一個(gè)數(shù)字,例如 <h1>。

    alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>

“打開(kāi)或關(guān)閉的不帶特性的 HTML 標(biāo)簽”的正則表達(dá)式:/<\/?[a-z][a-z0-9]*>/i

我們?cè)谀J介_(kāi)頭附近添加了一個(gè)可選的斜杠 /?。必須用一個(gè)反斜杠轉(zhuǎn)義它,否則 JavaScript 會(huì)認(rèn)為它是這個(gè)模式的結(jié)束符。

alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>

為了使正則表達(dá)式更精確,我們通常需要使其更復(fù)雜

我們能夠從這些例子中看到一個(gè)共同的規(guī)則:正則表達(dá)式越精確 —— 它就越長(zhǎng)越復(fù)雜。

例如,對(duì)于 HTML 標(biāo)簽,我們可以使用更簡(jiǎn)單的正則表達(dá)式:<\w+>。但是由于 HTML 對(duì)標(biāo)簽名稱有更嚴(yán)格的限制,所以 <[a-z][a-z0-9]*> 更可靠

我們可以使用 <\w+> 還是需要 <[a-z][a-z0-9]*>?

在實(shí)際開(kāi)發(fā)中,這兩種變體都是可以接受的。具體用哪個(gè)取決于我們對(duì)于“額外”匹配的寬容程度,以及通過(guò)其他方式將它們從結(jié)果中刪除的困難程度。

任務(wù)


如何找到省略號(hào) "..."?

重要程度: 5

創(chuàng)建一個(gè)正則表達(dá)式來(lái)查找省略號(hào):連續(xù) 3(或更多)個(gè)點(diǎn)。

例如:

let regexp = /你的正則表達(dá)式/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

解決方案

答案:

let regexp = /\.{3,}/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

請(qǐng)注意,點(diǎn)(.)是一個(gè)特殊字符,所以我們必須對(duì)其進(jìn)行轉(zhuǎn)義,即將其插入為 \.。


針對(duì) HTML 顏色的正則表達(dá)式

創(chuàng)建一個(gè)正則表達(dá)式來(lái)查找格式為 #ABCDEF 的 HTML 顏色值:首個(gè)字符是 #,后面緊接著的是六位的十六進(jìn)制字符。

用例:

let regexp = /...你的正則表達(dá)式.../

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678";

alert( str.match(regexp) )  // #121212,#AA00ef

P.S. 在這個(gè)任務(wù)中,我們不需要其他的顏色格式,例如 #123 或 rgb(1,2,3) 等。


解決方案

我們需要尋找首個(gè)字符是 #,后面緊接著的是六位的十六進(jìn)制字符的匹配項(xiàng)。

一個(gè)十六進(jìn)制字符可以描述為 [0-9a-fA-F]。如果我們使用修飾符 i,那么只需要 [0-9a-f]。

然后我們可以使用量詞 {6} 來(lái)查找其 6 個(gè)字符。

那么,我們得到正則表達(dá)式:/#[a-f0-9]{6}/gi

let regexp = /#[a-f0-9]{6}/gi;

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2"

alert( str.match(regexp) );  // #121212,#AA00ef

問(wèn)題是其從更長(zhǎng)的序列中匹配了顏色值:

alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #123456

為了解決這個(gè)問(wèn)題,我們可以在末尾加上 \b

// 顏色值
alert( "#123456".match( /#[a-f0-9]{6}\b/gi ) ); // #123456

// 不是顏色值
alert( "#12345678".match( /#[a-f0-9]{6}\b/gi ) ); // null


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)