Sady a rozsahy [...]

Několik znaků nebo tříd znaků uvnitř hranatých závorek […] znamená „hledat jakýkoli znak mezi danými“.

Sady

Například [eao] znamená kterýkoli ze 3 znaků:'a' , 'e' nebo 'o' .

Říká se tomu sada . Sady lze použít v regulárním výrazu spolu s běžnými znaky:

// find [t or m], and then "op"
alert( "Mop top".match(/[tm]op/gi) ); // "Mop", "top"

Vezměte prosím na vědomí, že ačkoliv je v sadě více znaků, odpovídají přesně jednomu znaku ve shodě.

Níže uvedený příklad tedy neposkytuje žádné shody:

// find "V", then [o or i], then "la"
alert( "Voila".match(/V[oi]la/) ); // null, no matches

Vzor hledá:

  • V ,
  • pak jedna z písmen [oi] ,
  • poté la .

Takže by existovala shoda pro Vola nebo Vila .

Rozsahy

Hranaté závorky mohou také obsahovat rozsahy znaků .

Například [a-z] je znak v rozsahu od a na z a [0-5] je číslice z 0 na 5 .

V níže uvedeném příkladu hledáme "x" následované dvěma číslicemi nebo písmeny z A na F :

alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) ); // xAF

Zde [0-9A-F] má dva rozsahy:hledá znak, který je buď číslicí z 0 na 9 nebo písmeno z A na F .

Pokud bychom chtěli hledat i malá písmena, můžeme přidat rozsah a-f :[0-9A-Fa-f] . Nebo přidejte příznak i .

Můžeme také použít znakové třídy uvnitř […] .

Pokud bychom například chtěli hledat slovní znak \w nebo spojovník - , pak je sada [\w-] .

Je také možné kombinovat více tříd, např. [\s\d] znamená „mezera nebo číslice“.

Třídy znaků jsou zkratky pro určité sady znaků

Například:

  • \d – je stejné jako [0-9] ,
  • \w – je stejné jako [a-zA-Z0-9_] ,
  • \s – je stejné jako [\t\n\v\f\r ] , plus několik dalších vzácných mezer Unicode.

Příklad:vícejazyčné \w

Jako třída znaků \w je zkratka pro [a-zA-Z0-9_] , nemůže najít čínské hieroglyfy, písmena azbuky atd.

Můžeme napsat univerzálnější vzor, ​​který hledá slovní znaky v jakémkoli jazyce. S vlastnostmi Unicode je to snadné:[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}] .

Pojďme to dešifrovat. Podobné jako \w , vytváříme vlastní sadu, která obsahuje znaky s následujícími vlastnostmi Unicode:

  • Alphabetic (Alpha ) – pro písmena,
  • Mark (M ) – pro akcenty,
  • Decimal_Number (Nd ) – pro číslice,
  • Connector_Punctuation (Pc ) – pro podtržítko '_' a podobné znaky,
  • Join_Control (Join_C ) – dva speciální kódy 200c a 200d , používané v ligaturách, např. v arabštině.

Příklad použití:

let regexp = /[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]/gu;

let str = `Hi 你好 12`;

// finds all letters and digits:
alert( str.match(regexp) ); // H,i,你,好,1,2

Tento vzor samozřejmě můžeme upravit:přidat vlastnosti Unicode nebo je odebrat. Vlastnosti Unicode jsou podrobněji popsány v článku Unicode:příznak "u" a třída \p{...}.

Vlastnosti Unicode nejsou v IE podporovány

Vlastnosti Unicode p{…} nejsou implementovány v IE. Pokud je opravdu potřebujeme, můžeme použít knihovnu XRegExp.

Nebo stačí použít rozsahy znaků v jazyce, který nás zajímá, např. [а-я] pro písmena azbuky.

Vyloučení rozsahů

Kromě normálních rozsahů existují „vylučující“ rozsahy, které vypadají jako [^…] .

Jsou označeny znakem stříšky ^ na začátku a shodujte se s libovolným znakem kromě daných .

Například:

  • [^aeyo] – jakýkoli znak kromě 'a' , 'e' , 'y' nebo 'o' .
  • [^0-9] – jakýkoli znak kromě číslice, stejný jako \D .
  • [^\s] – jakýkoli znak bez mezery, stejně jako \S .

Níže uvedený příklad hledá jakékoli znaky kromě písmen, číslic a mezer:

alert( "[email protected]".match(/[^\d\sA-Z]/gi) ); // @ and .

Útěk za […]

Obvykle, když chceme najít přesně speciální znak, potřebujeme jej escapovat jako \. . A pokud potřebujeme zpětné lomítko, pak použijeme \\ , a tak dále.

V hranatých závorkách můžeme použít naprostou většinu speciálních znaků bez escapování:

  • Symboly . + ( ) nikdy nepotřebujete uniknout.
  • Pomlčka - není uvozen na začátku ani na konci (kde nedefinuje rozsah).
  • stříška ^ je uniklé pouze na začátku (kde to znamená vyloučení).
  • Konečná hranatá závorka ] je vždy escapováno (pokud potřebujeme tento symbol hledat).

Jinými slovy, všechny speciální znaky jsou povoleny bez escapování, kromě případů, kdy něco znamenají hranaté závorky.

Tečka . uvnitř hranatých závorek znamená pouhou tečku. Vzor [.,] by hledal jeden ze znaků:buď tečku, nebo čárku.

V níže uvedeném příkladu regulární výraz [-().^+] hledá jeden ze znaků -().^+ :

// No need to escape
let regexp = /[-().^+]/g;

alert( "1 + 2 - 3".match(regexp) ); // Matches +, -

…Ale pokud se jim rozhodnete uniknout „pro každý případ“, pak by to nebylo na škodu:

// Escaped everything
let regexp = /[\-\(\)\.\^\+]/g;

alert( "1 + 2 - 3".match(regexp) ); // also works: +, -

Rozsahy a příznak „u“

Pokud jsou v sadě náhradní páry, označte u aby správně fungovaly.

Hledejme například [𝒳𝒴] v řetězci 𝒳 :

alert( '𝒳'.match(/[𝒳𝒴]/) ); // shows a strange character, like [?]
// (the search was performed incorrectly, half-character returned)

Výsledek je nesprávný, protože ve výchozím nastavení regulární výrazy „nevím“ o náhradních párech.

Modul regulárních výrazů si myslí, že [𝒳𝒴] – nejsou dva, ale čtyři znaky:

  1. levá polovina z 𝒳 (1) ,
  2. pravá polovina 𝒳 (2) ,
  3. levá polovina z 𝒴 (3) ,
  4. pravá polovina 𝒴 (4) .

Jejich kódy můžeme vidět takto:

for(let i=0; i<'𝒳𝒴'.length; i++) {
  alert('𝒳𝒴'.charCodeAt(i)); // 55349, 56499, 55349, 56500
};

Výše uvedený příklad tedy najde a ukáže levou polovinu 𝒳 .

Pokud přidáme příznak u , pak bude chování správné:

alert( '𝒳'.match(/[𝒳𝒴]/u) ); // 𝒳

Podobná situace nastává při hledání rozsahu, například [𝒳-𝒴] .

Pokud zapomeneme přidat příznak u , dojde k chybě:

'𝒳'.match(/[𝒳-𝒴]/); // Error: Invalid regular expression

Důvodem je, že bez příznaku u náhradní páry jsou vnímány jako dva znaky, takže [𝒳-𝒴] je interpretován jako [<55349><56499>-<55349><56500>] (každý náhradní pár je nahrazen svými kódy). Nyní je snadné vidět, že rozsah 56499-55349 je neplatný:jeho počáteční kód 56499 je větší než konec 55349 . To je formální důvod chyby.

S příznakem u vzor funguje správně:

// look for characters from 𝒳 to 𝒵
alert( '𝒴'.match(/[𝒳-𝒵]/u) ); // 𝒴