JavaScript používá pro řetězce kódování Unicode. Většina znaků je kódována 2 bajty, ale to umožňuje reprezentovat maximálně 65536 znaků.
Tento rozsah není dostatečně velký na zakódování všech možných znaků, proto jsou některé vzácné znaky kódovány 4 bajty, například 𝒳
(matematické X) nebo 😄
(úsměv), nějaké hieroglyfy a tak dále.
Zde jsou hodnoty Unicode některých znaků:
Postava | Unicode | Počet bajtů v Unicode |
---|---|---|
a | 0x0061 | 2 |
≈ | 0x2248 | 2 |
𝒳 | 0x1d4b3 | 4 |
𝒴 | 0x1d4b4 | 4 |
😄 | 0x1f604 | 4 |
Tedy znaky jako a
a ≈
zabírají 2 bajty, zatímco kódy pro 𝒳
, 𝒴
a 😄
jsou delší, mají 4 bajty.
Kdysi dávno, když byl vytvořen jazyk JavaScript, bylo kódování Unicode jednodušší:neexistovaly žádné 4bajtové znaky. Některé jazykové funkce je tedy stále zpracovávají nesprávně.
Například length
si myslí, že zde jsou dva znaky:
alert('😄'.length); // 2
alert('𝒳'.length); // 2
…Ale vidíme, že je jen jeden, že? Jde o to, že length
považuje 4 bajty za dva 2bajtové znaky. To je nesprávné, protože se musí posuzovat pouze společně (tzv. „náhradní pár“, můžete si o nich přečíst v článku Řetězce).
Ve výchozím nastavení regulární výrazy také považují 4bajtové „dlouhé znaky“ za dvojici dvoubajtových znaků. A jak se to stává u řetězců, může to vést k lichým výsledkům. To uvidíme o něco později, v článku Sady a rozsahy [...].
Na rozdíl od řetězců mají regulární výrazy příznak u
který řeší takové problémy. S takovým příznakem regulární výraz správně zpracovává 4bajtové znaky. A také bude k dispozici vyhledávání vlastností Unicode, k tomu se dostaneme příště.
Vlastnosti Unicode \p{…}
Každý znak v Unicode má mnoho vlastností. Popisují, do jaké „kategorie“ postava patří, obsahují o ní různé informace.
Pokud má například znak Letter
vlastnost, to znamená, že znak patří do abecedy (jakéhokoli jazyka). A Number
vlastnost znamená, že je to číslice:možná arabština nebo čínština a tak dále.
Můžeme hledat znaky s vlastností, zapsanou jako \p{…}
. Chcete-li použít \p{…}
, regulární výraz musí mít příznak u
.
Například \p{Letter}
označuje písmeno v jakémkoli jazyce. Můžeme také použít \p{L}
, jako L
je alias Letter
. Téměř pro každou vlastnost existují kratší aliasy.
V níže uvedeném příkladu budou nalezeny tři druhy písmen:angličtina, gruzínština a korejština.
let str = "A ბ ㄱ";
alert( str.match(/\p{L}/gu) ); // A,ბ,ㄱ
alert( str.match(/\p{L}/g) ); // null (no matches, \p doesn't work without the flag "u")
Zde jsou hlavní kategorie postav a jejich podkategorie:
- Písmeno
L
:- malé
Ll
- modifikátor
Lm
, - titlecase
Lt
, - velká
Lu
, - jiné
Lo
.
- malé
- Číslo
N
:- desetinná číslice
Nd
, - číslo písmene
Nl
, - jiné
No
.
- desetinná číslice
- Interpunkce
P
:- konektor
Pc
, - pomlčka
Pd
, - počáteční citace
Pi
, - konečná nabídka
Pf
, - otevřete
Ps
, - zavřete
Pe
, - jiné
Po
.
- konektor
- Označte
M
(akcenty atd.):- kombinace mezer
Mc
, - ohraničující
Me
, - bez mezer
Mn
.
- kombinace mezer
- Symbol
S
:- měna
Sc
, - modifikátor
Sk
, - matematické
Sm
, - jiné
So
.
- měna
- Oddělovač
Z
:- řádek
Zl
, - odstavec
Zp
, - mezera
Zs
.
- řádek
- Jiné
C
:- ovládejte
Cc
, - formát
Cf
, - není přiřazeno
Cn
, - soukromé použití
Co
, - náhradní
Cs
.
- ovládejte
Takže např. pokud potřebujeme malá písmena, můžeme napsat \p{Ll}
, interpunkční znaménka:\p{P}
a tak dále.
Existují také další odvozené kategorie, například:
Alphabetic
(Alpha
), zahrnuje písmenaL
, plus čísla písmenNl
(např. Ⅻ – znak pro římské číslo 12) plus některé další symbolyOther_Alphabetic
(OAlpha
).Hex_Digit
obsahuje hexadecimální číslice:0-9
,a-f
.- …A tak dále.
Unicode podporuje mnoho různých vlastností, jejich úplný seznam by vyžadoval hodně místa, takže zde jsou odkazy:
- Seznam všech vlastností podle znaku:https://unicode.org/cldr/utility/character.jsp.
- Seznam všech znaků podle vlastnosti:https://unicode.org/cldr/utility/list-unicodeset.jsp.
- Krátké aliasy pro vlastnosti:https://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt.
- Úplný základ znaků Unicode v textovém formátu se všemi vlastnostmi naleznete zde:https://www.unicode.org/Public/UCD/latest/ucd/.
Příklad:hexadecimální čísla
Podívejme se například na hexadecimální čísla zapsaná jako xFF
, kde F
je hexadecimální číslice (0…9 nebo A…F).
Hexadecimální číslici lze označit jako \p{Hex_Digit}
:
let regexp = /x\p{Hex_Digit}\p{Hex_Digit}/u;
alert("number: xAF".match(regexp)); // xAF
Příklad:čínské hieroglyfy
Hledejme čínské hieroglyfy.
Existuje vlastnost Unicode Script
(systém zápisu), který může mít hodnotu:Cyrillic
, Greek
, Arabic
, Han
(čínština) a tak dále, zde je úplný seznam.
K vyhledání znaků v daném systému psaní bychom měli použít Script=<value>
, např. pro písmena azbuky:\p{sc=Cyrillic}
, pro čínské hieroglyfy:\p{sc=Han}
, a tak dále:
let regexp = /\p{sc=Han}/gu; // returns Chinese hieroglyphs
let str = `Hello Привет 你好 123_456`;
alert( str.match(regexp) ); // 你,好
Příklad:měna
Znaky označující měnu, například $
, €
, ¥
, mají vlastnost Unicode \p{Currency_Symbol}
, krátký alias:\p{Sc}
.
Použijme jej k vyhledání cen ve formátu „měna, za kterou následuje číslice“:
let regexp = /\p{Sc}\d/gu;
let str = `Prices: $2, €1, ¥9`;
alert( str.match(regexp) ); // $2,€1,¥9
Později v článku Kvantifikátory +, *, ? a {n} uvidíme, jak hledat čísla, která obsahují mnoho číslic.
Shrnutí
Označte u
umožňuje podporu Unicode v regulárních výrazech.
To znamená dvě věci:
- Znaky o délce 4 bajtů jsou zpracovány správně:jako jeden znak, nikoli dva dvoubajtové znaky.
- Při vyhledávání lze použít vlastnosti Unicode:
\p{…}
.
Pomocí vlastností Unicode můžeme hledat slova v daných jazycích, speciální znaky (uvozovky, měny) a tak dále.