W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
JavaScript 對(duì)字符串使用 Unicode 編碼。大多數(shù)字符使用 2 個(gè)字節(jié)編碼,但這種方式只能編碼最多 65536 個(gè)字符。
這個(gè)范圍不足以對(duì)所有可能的字符進(jìn)行編碼,這就是為什么使用 4 個(gè)字節(jié)對(duì)一些罕見(jiàn)的字符進(jìn)行編碼,比如 (數(shù)學(xué)符號(hào) X)或
(笑臉),一些象形文字等等。
下面是一些字符對(duì)應(yīng)的 Unicode 值:
字符 | Unicode | Unicode 中的字節(jié)數(shù) |
---|---|---|
a | 0x0061
|
2 |
≈ | 0x2248
|
2 |
0x1d4b3
|
4 | |
0x1d4b4
|
4 | |
0x1f604
|
4 |
所以像 a
和 ≈
這樣的字符占用 2 個(gè)字節(jié),而 ,
和
的對(duì)應(yīng)編碼則更長(zhǎng),占用 4 個(gè)字節(jié)。
很久以前,當(dāng) JavaScript 被發(fā)明出來(lái)的時(shí)候,Unicode 編碼要更加簡(jiǎn)單:當(dāng)時(shí)沒(méi)有 4 個(gè)字節(jié)的字符。所以,有些語(yǔ)言功能現(xiàn)在仍無(wú)法正確處理它們。
比如 length
認(rèn)為這里有 2 個(gè)字符:
alert(''.length); // 2
alert(''.length); // 2
……但我們可以清楚地認(rèn)識(shí)到這里只有一個(gè)字符,對(duì)吧?關(guān)鍵在于 length
把 4 個(gè)字節(jié)當(dāng)成了 2 個(gè) 2 字節(jié)長(zhǎng)的字符。這是不對(duì)的,因?yàn)樗鼈儽仨毐划?dāng)作一個(gè)整體來(lái)考慮(即所謂的“代理對(duì)(surrogate pair)”,你可以在 字符串 中閱讀關(guān)于代理對(duì)的更多信息)。
默認(rèn)情況下,正則表達(dá)式也會(huì)把一個(gè) 4 個(gè)字節(jié)的“長(zhǎng)字符”當(dāng)成一對(duì) 2 個(gè)字節(jié)長(zhǎng)的字符。正如在字符串中遇到的情況,這將導(dǎo)致一些奇怪的結(jié)果。我們很快會(huì)在后面的章節(jié) 集合和范圍 [...] 中遇到。
與字符串有所不同的是,正則表達(dá)式有一個(gè)修飾符 u
被用以解決此類問(wèn)題。當(dāng)一個(gè)正則表達(dá)式帶有這個(gè)修飾符后,4 個(gè)字節(jié)長(zhǎng)的字符將被正確地處理。同時(shí)也能夠使用 Unicode 屬性進(jìn)行查找了,我們接下來(lái)就一起學(xué)習(xí)它吧。
Unicode 中的每個(gè)字符都有很多屬性。它們描述了字符所屬的“類別”,包含了關(guān)于字符的各種信息。
例如,如果一個(gè)字符具有 Letter
屬性,這意味著這個(gè)字符歸屬于(任意語(yǔ)言的)字母表。而 Number
屬性則表示這是一個(gè)數(shù)字:也許是阿拉伯?dāng)?shù)字,亦或是中文數(shù)字,等等。
我們可以查找具有某種屬性的字符,寫作 \p{…}
。為了使用 \p{…}
,一個(gè)正則表達(dá)式必須使用修飾符 u
。
舉個(gè)例子,\p{Letter}
表示任何語(yǔ)言中的一個(gè)字母。我們也可以使用 \p{L}
,因?yàn)?nbsp;L
是 Letter
的一個(gè)別名。對(duì)于每種屬性而言,幾乎都存在對(duì)應(yīng)的縮寫別名。
在下面的例子中會(huì)找出來(lái) 3 種字母:英語(yǔ)、格魯吉亞語(yǔ)和韓語(yǔ)。
let str = "A ? ?";
alert( str.match(/\p{L}/gu) ); // A,?,?
alert( str.match(/\p{L}/g) ); // null(沒(méi)有匹配項(xiàng),因?yàn)闆](méi)有修飾符 "u")
以下是主要的字符類別和它們對(duì)應(yīng)的子類別:
L
:
Ll
,Lm
,Lt
,Lu
,Lo
。N
:
Nd
,Nl
,No
。P
:
Pc
,Pd
,Pi
,Pf
,Ps
,Pe
,Po
。M
(accents etc):
Mc
,Me
,Mn
。S
:
Sc
,Sk
,Sm
,So
。Z
:
Zl
,Zp
,Zs
。C
:
Cc
,Cf
,Cn
,Co
,Cs
。因此,比如說(shuō)我們需要小寫的字母,就可以寫成 \p{Ll}
,標(biāo)點(diǎn)符號(hào)寫作 \p{P}
等等。
也有其它派生的類別,例如:
Alphabetic
(Alpha
),包含了字母 L
,加上字母數(shù)字 Nl
(例如 Ⅻ —— 羅馬數(shù)字 12),加上一些其它符號(hào) Other_Alphabetic
(OAlpha
)。Hex_Digit
包括 16 進(jìn)制數(shù)字 0-9
,a-f
。Unicode 支持很多不同的屬性,列出整個(gè)清單需要占用大量的篇幅,因此在這里列出相關(guān)的鏈接:
舉個(gè)例子,讓我們來(lái)查找 16 進(jìn)制數(shù)字,寫作 xFF
其中 F
是一個(gè) 16 進(jìn)制的數(shù)字(0…9 或者 A…F)。
一個(gè) 16 進(jìn)制數(shù)字可以表示為 \p{Hex_Digit}
:
let regexp = /x\p{Hex_Digit}\p{Hex_Digit}/u;
alert("number: xAF".match(regexp)); // xAF
讓我們?cè)賮?lái)查找中文字符。
有一個(gè) Unicode 屬性 Script
(一個(gè)書寫系統(tǒng)),這個(gè)屬性可能有一個(gè)值:Cyrillic
、Greek
、Arabic
、Han
(中文)等等,這里是一個(gè)完整的列表。
要在給定的書寫系統(tǒng)中查找字符,我們需要使用 Script=<value>
,例如對(duì)于西里爾字母:\p{sc=Cyrillic}
,中文象形文字:\p{sc=Han}
,等等。
let regexp = /\p{sc=Han}/gu; // 返回中文象形文字
let str = `Hello Привет 你好 123_456`;
alert( str.match(regexp) ); // 你,好
表示貨幣的字符,例如 $
、€
和 ¥
,具有 Unicode 屬性 \p{Currency_Symbol}
,縮寫為 \p{Sc}
。
讓我們用它來(lái)查找格式為“貨幣,接著是一個(gè)數(shù)字”的價(jià)格:
let regexp = /\p{Sc}\d/gu;
let str = `Prices: $2, €1, ¥9`;
alert( str.match(regexp) ); // $2,€1,¥9
稍后,在文章 量詞 +, *, ? 和 {n} 中我們將學(xué)習(xí)如何查找包含很多位的數(shù)字。
修飾符 u
表示啟用正則表達(dá)式中對(duì) Unicode 的支持。
這意味著兩件事:
\p{…}
?。有了 unicode 屬性我們可以查找給定語(yǔ)言中的詞,特殊字符(引用,貨幣)等等。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: