Přeskočit na obsah

Tahák na regulární výrazy

Regulární výrazy jsou dostatečně úsporné na to, že se syntaxe snáze dohledá, než zapamatuje. Tato stránka je celá na jedné obrazovce — třídy, kvantifikátory, kotvy, skupiny, lookaround, escapování a příznaky — s funkčním příkladem pro každý řádek.

Použitým dialektem je JavaScript, který běží ve vašem prohlížeči a který používá tester regulárních výrazů na tomto webu. Většina toho je identická v Pythonu, Javě, Go a PCRE; kde se dialekty rozcházejí, rozcházejí se na okrajích — podpora lookbehind, syntaxe pojmenovaných skupin a to, zda \d znamená „ASCII číslice“, nebo „jakákoli číslice Unicode“.

Za většinu překvapení mohou dvě věci. Kvantifikátory jsou hladové: berou všechno, co mohou, a vracejí zpět jen tehdy, když zbytek vzoru selže, což je důvod, proč <.+> spolkne dvě značky a <.+?> ne. A alternace váže ze všeho nejvolněji, takže ^a|b$ znamená „začíná na a, nebo končí na b“ — ne to, co většina lidí zamýšlí, když to napíše.

Třídy znaků

11

Zkratky jsou pouze ASCII, pokud nepřidáte příznak u a nepoužijete escape sekvence vlastností Unicode.

SyntaxeVýznamPříklad
.Jakýkoli znak kromě zalomení řádkuPřidejte příznak s, aby odpovídal i novým řádkům./a.c/"abc" "abc"
\dČíslice, 0–9/\d+/"order 42" "42"
\DCokoli, co není číslice/\D+/"42abc" "abc"
\wPísmeno, číslice nebo podtržítkoPouze ASCII — „é“ není \w./\w+/"user_1!" "user_1"
\WCokoli, čemu \w neodpovídá/\W+/"a++b" "++"
\sJakýkoli bílý znak, včetně tabulátorů a nových řádků/\s+/"a \t b" " \t "
\SJakýkoli znak, který není bílý/\S+/" hi" "hi"
[abc]Kterýkoli z uvedených znaků/[aeiou]/"rhythm and" "a"
[^abc]Jakýkoli znak kromě uvedených/[^aeiou ]+/"aeiou xyz" "xyz"
[a-z]Rozsah znaků/[a-f]+/"zzabcz" "abc"
\p{L}Jakékoli písmeno Unicode (vyžaduje příznak u)/\p{L}+/"42 café" "café"

Kvantifikátory

7

Všechny jsou ve výchozím stavu hladové: berou co nejvíce a vracejí zpět jen tehdy, když zbytek vzoru selže.

SyntaxeVýznamPříklad
*Nula nebo více/ab*/"a" "a"
+Jeden nebo více/ab+/"abbb" "abbb"
?Nula nebo jeden — činí to nepovinným/colou?r/"color" "color"
{3}Přesně tři/\d{3}/"id 12345" "123"
{2,}Dva nebo více/a{2,}/"aaa" "aaa"
{2,4}Mezi dvěma a čtyřmi/a{2,4}/"aaaaa" "aaaa"
*?Líný — shodí co nejméněHladový <.+> by spolkl obě značky./<.+?>/"<a><b>" "<a>"

Kotvy a hranice

4

Odpovídají pozici, nikoli znaku, takže nespotřebují nic.

SyntaxeVýznamPříklad
^Začátek řetězce, nebo řádku s příznakem m/^a/"abc" "a"
$Konec řetězce, nebo řádku s příznakem m/c$/"abc" "c"
\bHranice slovaTo je to, co zabrání, aby „cat“ odpovídalo uvnitř „concatenate“./\bcat\b/"the cat sat" "cat"
\BNe hranice slova/\Bcat/"concatenate" "cat"

Skupiny a alternace

5
SyntaxeVýznamPříklad
(abc)Zachytávající skupina — zapamatována pro náhradu/(\d+)-(\d+)/"10-20" "10-20"
(?:abc)Seskupení bez zachyceníPoužijte to, když potřebujete jen seskupení; zachovává to smysluplnost čísel zachycení./(?:ab)+/"abab" "abab"
(?<name>…)Pojmenovaná zachytávající skupina/(?<year>\d{4})/"in 2026" "2026"
a|bKterákoli strana — alternaceAlternace má nejnižší prioritu: ^a|b$ je „^a“ nebo „b$“, nikoli „^(a|b)$“./cat|dog/"one dog" "dog"
\1Zpětný odkaz na první skupinu/(\w)\1/"letter" "tt"

Lookaround

4

Tvrzení o tom, co pozici obklopuje. Sama neodpovídají ničemu, což je činí bezpečnými pro kombinování.

SyntaxeVýznamPříklad
(?=…)Lookahead — následováno tímto/\d+(?= kg)/"80 kg" "80"
(?!…)Negativní lookahead — nenásledováno tímto/\d+(?! kg)/"80 lb" "80"
(?<=…)Lookbehind — předcházeno tímto/(?<=\$)\d+/"costs $40" "40"
(?<!…)Negativní lookbehind — nepředcházeno tímto/(?<!\$)\b\d+/"about 40" "40"

Escapování

5

Těchto dvanáct znaků je těch, které potřebují zpětné lomítko, aby byly brány doslovně.

SyntaxeVýznamPříklad
\.Doslovná tečka/\d\.\d/"v2.5" "2.5"
\\Doslovné zpětné lomítko/\\/"C:\\dir" "\\"
\nLine feed/a\nb/"a\nb" "a\nb"
\tTabulátor/a\tb/"a\tb" "a\tb"
\uFFFFZnak podle jeho kódového bodu/\u00e9/"café" "é"

Příznaky

6
PříznakNázevVýznam
gGlobalNajde každou shodu, nejen první.
iIgnorovat velikost písmenOdpovídá bez ohledu na velká či malá písmena.
mMultilineZpůsobí, že ^ a $ odpovídají na každém zalomení řádku místo jen na koncích řetězce.
sDot allUmožní, aby . odpovídalo i zalomením řádku.
uUnicodeZachází se vzorem jako s kódovými body a povoluje escape sekvence vlastností \p{…}.
yStickyOdpovídá pouze přesně na lastIndex, nikdy nehledá dopředu.

Časté dotazy

Jaký je rozdíl mezi hladovými a línými kvantifikátory?
Hladové kvantifikátory (*, +, {2,}) shodí co nejvíce a vracejí znaky zpět jen tehdy, když zbytek vzoru nemůže odpovídat. Přidání ? je učiní línými: shodí co nejméně a berou víc jen tehdy, když jsou k tomu donuceny. Na „<a><b>“ vrátí vzor <.+> celý řetězec a <.+?> vrátí jen <a>.
Proč mi slovo odpovídá uvnitř jiných slov?
Protože ho nic neukotvilo. Obalte slovo do \b — /\bcat\b/ odpovídá „cat“ v „the cat sat“, ale ne uvnitř „concatenate“. \b odpovídá pozici mezi slovním znakem a neslovním, takže nespotřebuje nic.
Co mění příznak u?
Způsobí, že vzor pracuje s kódovými body místo s jednotkami UTF-16, takže jediné emoji se počítá jako jeden znak, a povolí escape sekvence vlastností \p{…}, jako je \p{L} pro „jakékoli písmeno“. Bez něj zůstávají \w a \d pouze ASCII, což je důvod, proč „café“ plně neodpovídá /\w+/.
Kdy mám použít nezachytávající skupinu?
Kdykoli potřebujete seskupení, ale ne zachycený text — (?:ab)+ místo (ab)+. Zachycení stojí trochu výkonu, ale skutečným důvodem je číslování: každá zachytávající skupina, kterou přidáte, posune čísla těch za ní a nenápadně rozbije náhrady, které používají $1 a $2.
Je bezpečné používat lookbehind?
V současných prohlížečích a Node ano — (?<=…) a (?<!…) jsou podporovány ve všech hlavních enginech od roku 2018. Safari ho přidalo jako poslední. Pokud cílíte na velmi staré běhové prostředí, ověřte to nejdřív; pro syntaxi regulárních výrazů neexistuje polyfill.