Dívat se dopředu a dívat se dozadu

Někdy potřebujeme najít pouze ty shody se vzorem, které následuje nebo předchází jiný vzor.

Pro to existuje speciální syntaxe, nazvaná „lookahead“ a „lookbehind“, společně označovaná jako „lookaround“.

Pro začátek najděte cenu z řetězce jako 1 turkey costs 30€ . To znamená:číslo následované podepsat.

Lookahead

Syntaxe je:X(?=Y) , to znamená "hledejte X , ale shodují se pouze v případě, že následuje Y ". Místo X může být jakýkoli vzor a Y .

Pro celé číslo následované , regulární výraz bude \d+(?=€) :

let str = "1 turkey costs 30€";

alert( str.match(/\d+(?=€)/) ); // 30, the number 1 is ignored, as it's not followed by €

Upozornění:výhled je pouze test, obsah závorek (?=...) není zahrnuto ve výsledku 30 .

Když hledáme X(?=Y) , modul regulárních výrazů najde X a poté zkontroluje, zda je zde Y hned po něm. Pokud tomu tak není, potenciální shoda je přeskočena a hledání pokračuje.

Jsou možné složitější testy, např. X(?=Y)(?=Z) znamená:

  1. Najděte X .
  2. Zkontrolujte, zda Y je bezprostředně za X (není-li, přeskočte).
  3. Zkontrolujte, zda Z je také bezprostředně za X (není-li, přeskočte).
  4. Pokud oba testy prošly úspěšně, pak X je shoda, jinak pokračujte v hledání.

Jinými slovy, takový vzor znamená, že hledáme X následuje Y a Z ve stejnou dobu.

To je možné pouze v případě, že vzory Y a Z se vzájemně nevylučují.

Například \d+(?=\s)(?=.*30) hledá \d+ za kterým následuje mezera (?=\s) a je tam 30 někde za ním (?=.*30) :

let str = "1 turkey costs 30€";

alert( str.match(/\d+(?=\s)(?=.*30)/) ); // 1

V našem řetězci, který přesně odpovídá číslu 1 .

Negativní výhled

Řekněme, že chceme místo toho množství, nikoli cenu ze stejného řetězce. To je číslo \d+ , NE následované .

K tomu lze použít negativní výhled.

Syntaxe je:X(?!Y) , znamená to "hledat X , ale pouze pokud není následováno Y ".

."
let str = "2 turkeys cost 60€";

alert( str.match(/\d+\b(?!€)/g) ); // 2 (the price is not matched)

Podívejte se za sebou

Lookbehind kompatibilita prohlížeče

Poznámka:Lookbehind není podporován v prohlížečích jiných než V8, jako je Safari, Internet Explorer.

Lookahead umožňuje přidat podmínku pro „co následuje“.

Lookbehind je podobný, ale dívá se dozadu. To znamená, že umožňuje shodu se vzorem pouze v případě, že je před ním něco.

Syntaxe je:

  • Pozitivní vzhled:(?<=Y)X , odpovídá X , ale pouze v případě, že existuje Y před tím.
  • Negativní lookbehind:(?<!Y)X , odpovídá X , ale pouze v případě, že neexistuje Y před tím.

Změňme například cenu na americké dolary. Znak dolaru je obvykle před číslem, takže hledejte $30 použijeme (?<=\$)\d+ – částka, které předchází $ :

let str = "1 turkey costs $30";

// the dollar sign is escaped \$
alert( str.match(/(?<=\$)\d+/) ); // 30 (skipped the sole number)

A pokud potřebujeme množství – číslo, před kterým není $ , pak můžeme použít negativní lookbehind (?<!\$)\d+ :

let str = "2 turkeys cost $60";

alert( str.match(/(?<!\$)\b\d+/g) ); // 2 (the price is not matched)

Zachycení skupin

Obsah uvnitř závorek se obecně nestává součástí výsledku.

Např. ve vzoru \d+(?=€) , znamení není zachyceno jako součást zápasu. To je přirozené:hledáme číslo \d+ , zatímco (?=€) je pouze test, že by měl následovat .

Ale v některých situacích můžeme chtít zachytit i výraz rozhledu nebo jeho část. To je možné. Stačí zabalit tuto část do dalších závorek.

V níže uvedeném příkladu znak měny (€|kr) je zachycen spolu s částkou:

let str = "1 turkey costs 30€";
let regexp = /\d+(?=(€|kr))/; // extra parentheses around €|kr

alert( str.match(regexp) ); // 30, €

A totéž platí pro lookbehind:

let str = "1 turkey costs $30";
let regexp = /(?<=(\$|£))\d+/;

alert( str.match(regexp) ); // 30, $

Shrnutí

Lookahead a lookbehind (běžně označované jako „lookaround“) jsou užitečné, když chceme něco porovnat v závislosti na kontextu před tím a po něm.

Pro jednoduché regulární výrazy můžeme podobnou věc provést ručně. To znamená:porovnejte vše, v jakémkoli kontextu a poté filtrujte podle kontextu ve smyčce.

Pamatujte, str.match (bez příznaku g ) a str.matchAll (vždy) vrátí shody jako pole s index vlastnost, takže víme, kde přesně se v textu nachází, a můžeme zkontrolovat kontext.

Ale obecně je pohodlnější se dívat kolem sebe.

Typy pohledu:

Vzor type shody
X(?=Y) Pozitivní výhled X pokud následuje Y
X(?!Y) Negativní výhled X pokud není následováno Y
(?<=Y)X Pozitivní vzhled X pokud po Y
(?<!Y)X Negativní pohled na pozadí X pokud ne po Y