Unicode:příznak u a třída \p{...}

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 .
  • Číslo N :
    • desetinná číslice Nd ,
    • číslo písmene Nl ,
    • jiné No .
  • 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 .
  • Označte M (akcenty atd.):
    • kombinace mezer Mc ,
    • ohraničující Me ,
    • bez mezer Mn .
  • Symbol S :
    • měna Sc ,
    • modifikátor Sk ,
    • matematické Sm ,
    • jiné So .
  • Oddělovač Z :
    • řádek Zl ,
    • odstavec Zp ,
    • mezera Zs .
  • Jiné C :
    • ovládejte Cc ,
    • formát Cf ,
    • není přiřazeno Cn ,
    • soukromé použití Co ,
    • náhradní Cs .

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ísmena L , plus čísla písmen Nl (např. Ⅻ – znak pro římské číslo 12) plus některé další symboly Other_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:

  1. Znaky o délce 4 bajtů jsou zpracovány správně:jako jeden znak, nikoli dva dvoubajtové znaky.
  2. 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.