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“.
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ódy200c
a200d
, 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:
- levá polovina z
𝒳
(1)
, - pravá polovina
𝒳
(2)
, - levá polovina z
𝒴
(3)
, - 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) ); // 𝒴