js пространство за регулярни изрази. Регулярни изрази. Използване на match и exec без групи

Регулярни изрази

Редовен изразе обект, който описва символен модел. Класът RegExp в JavaScript представлява регулярни изрази, а обектите на класовете String и RegExp дефинират методи, които използват регулярни изрази за извършване на операции за съвпадение на шаблони и замяна на текст. Граматиката на регулярните изрази в JavaScript съдържа доста пълно подмножество от синтаксиса на регулярните изрази, използван в Perl 5, така че ако сте запознати с Perl, трябва да можете да пишете шаблони в програми на JavaScript с лекота.

Характеристиките на регулярните изрази на Perl, които не се поддържат в ECMAScript, включват флаговете s (едноредов режим) и x (разширен синтаксис); escape последователностите \a, \e, \l, \u, \L, \U, \E, \Q, \A, \Z, \z и \G и други разширени конструкции, започващи с (?.

Дефиниране на регулярни изрази

В JavaScript регулярните изрази са представени от обекти. Regexp. Обектите RegExp могат да бъдат създадени с помощта на конструктора RegExp(), но по-често те се създават с помощта на специален литерал синтаксис. Точно както низовите литерали са посочени като знаци, затворени в кавички, литералите на регулярните изрази са посочени като знаци, затворени в двойка наклонени черти (/). По този начин JavaScript кодът може да съдържа редове, подобни на този:

Varpattern = /s$/;

Този ред създава нов обект RegExp и го присвоява на променливата на шаблона. Този обект на RegExp търси всички низове, които завършват с "s". Същият регулярен израз може да бъде дефиниран с помощта на конструктора RegExp():

Varpattern = new RegExp("s$");

Спецификацията на модела на регулярен израз се състои от поредица от знаци. Повечето знаци, включително всички буквено-цифрови знаци, буквално описват знаците, които трябва да присъстват. Тоест, регулярният израз /java/ съвпада с всички низове, съдържащи подниз "java".

Други знаци в регулярните изрази не са предназначени да бъдат търсени за техните точни еквиваленти, но имат специално значение. Например регулярният израз /s$/ съдържа два знака. Първият символ s означава търсене на буквален знак. Вторият, $, е специален метазнак, който маркира края на ред. Така че този регулярен израз съответства на всеки низ, който завършва с s.

Следващите раздели описват различните знаци и метазнаци, използвани в регулярните изрази на JavaScript.

Буквални символи

Както беше отбелязано по-рано, всички азбучни знаци и числа в регулярните изрази съвпадат сами по себе си. Синтаксисът на регулярните изрази в JavaScript също така поддържа възможността да се определят определени не азбучни знаци, като се използват escape последователности, които започват с обратна наклонена черта (\). Например, последователността \n съответства на символа за нов ред. Тези знаци са изброени в таблицата по-долу:

Някои препинателни знаци имат специално значение в регулярните изрази:

^ $ . * + ? = ! : | \ / () { } -

Значението на тези символи е обяснено в следващите раздели. Някои от тях имат специално значение само в определени контексти на регулярни изрази, докато в други контексти се приемат буквално. Въпреки това, като цяло, за да включите някой от тези знаци буквално в регулярен израз, трябва да го предхождате с обратна наклонена черта. Други знаци, като кавички и @, нямат специално значение и просто съвпадат в регулярни изрази.

Ако не можете да си спомните точно кой знак трябва да бъде предшестван от \, можете спокойно да поставите обратна наклонена черта преди всеки от знаците. Имайте предвид обаче, че много букви и цифри придобиват специално значение заедно с наклонената черта, така че буквите и цифрите, които търсите буквално, не трябва да се предхождат от \. За да включите самия обратна наклонена черта в регулярния израз, очевидно трябва да го предхождате с друг обратна наклонена черта. Например, следният регулярен израз съответства на всеки низ, съдържащ обратна наклонена черта: /\\/.

Класове по персонажи

Отделните буквални знаци могат да бъдат комбинирани в класове знаци, като ги оградите в квадратни скоби. Класът на знаците съответства на всеки знак, съдържащ се в този клас. Следователно регулярният израз // съответства на един от символите a, b или c.

Могат да бъдат дефинирани и класове с отрицателни знаци, отговарящи на всеки знак, различен от тези, дадени в скоби. Класът на отрицателния знак се посочва от знака ^ като първи знак след лявата скоба. Регулярният израз /[^abc]/ съответства на всеки знак, различен от a, b или c. В класовете от знаци може да се посочи диапазон от знаци с тире. Всички малки латински знаци се търсят с помощта на // израза и всяка буква или цифра от набора от латински знаци може да бъде намерена с помощта на израза //.

Определени класове знаци се използват особено често, така че синтаксисът на регулярните изрази на JavaScript включва специални знаци и escape последователности за тяхното обозначаване. Например, \s съответства на интервали, табулатори и всякакви бели знаци от набора Unicode, а \S съответства на всички знаци, които не са празни интервали от набора Unicode.

Таблицата по-долу изброява тези специални знаци и синтаксиса на класовете знаци. (Обърнете внимание, че някои от escape-последователностите на класа на знаците съвпадат само с ASCII знаци и не са разширени за работа с Unicode знаци. Можете изрично да дефинирате свои собствени Unicode символни класове, например /[\u0400-\u04FF]/ съответства на всеки знак на кирилица. )

Класове символи с регулярни изрази на JavaScript
символ Съответствие
[...] Всеки от знаците в скоби
[^...] Всеки от знаците, които не са в скобите
. Всеки знак, различен от нов ред или друг разделител на низове в Unicode
\w Всеки ASCII текстов символ. Еквивалентно
\W Всеки знак, който не е ASCII текстов символ. Еквивалентно на [^a-zA-Z0-9_]
Всеки празен символ от набора Unicode
Всеки знак, който не е празен интервал от набора от символи на Unicode. Обърнете внимание, че \w и \S не са еднакви
Всички ASCII цифри. Еквивалентно
Всеки знак, различен от ASCII цифри. Еквивалентно на [^0-9]
[\b] символен литерал за връщане

Обърнете внимание, че последователностите за избягване на специални символи на класа могат да бъдат затворени в квадратни скоби. \s съответства на всеки символ за интервал и \d съответства на всяка цифра, така че /[\s\d]/ съответства на всеки символ на интервал или цифра.

Повторение

С придобитите досега познания за синтаксиса на регулярните изрази, можем да опишем двуцифрено число като /\d\d/ или четирицифрено число като /\d\d\d\d/, но не можем, напр. , описват число, състоящо се от произволен брой цифри, или низ от три букви, последван от незадължителна цифра. Тези по-сложни модели използват синтаксис на регулярен израз, за ​​да укажат колко пъти даден елемент на регулярен израз може да бъде повторен.

Символите, обозначаващи повторение, винаги следват модела, към който се прилагат. Някои видове повторения се използват доста често и има специални символи за тези случаи. Например, + съответства на един или повече екземпляри на предишния модел. Следната таблица е обобщение на синтаксиса на повторението:

Следните редове показват някои примери:

Varpattern = /\d(2,4)/; // Съвпада с число, съдържащо две до четири цифри pattern = /\w(3)\d?/; // Съвпада точно с три символа на думи и една незадължителна цифра = /\s+java\s+/; // Съпоставя думата "java" с един или повече интервали // преди и след нея pattern = /[^(]*/; // Съвпада с нула или повече символи, различни от отварящата скоба

Бъдете внимателни, когато използвате повтарящите се знаци * и ?. Те могат да съответстват на липсата на модел, предшестван от тях, и следователно на отсъствието на знаци. Например, регулярният израз /a*/ съответства на низа "bbbb", тъй като не съдържа символа a.

Изброените в таблицата знаци за повторение отговарят на максималния възможен брой повторения, което осигурява търсенето на следващите части от регулярния израз. Казваме, че това е "алчно" повторение. Възможно е също така да се приложи повторение по "неалчен" начин. Достатъчно е да посочите въпросителен знак след знака (или знаците) на повторението: ??, +?, *? или дори (1,5)?.

Например, регулярният израз /a+/ съответства на един или повече екземпляри на буквата a. Приложен към низа "aaa", той отговаря на трите букви. От друга страна, /a+?/ съвпада с един или повече екземпляри на буквата a и избира възможно най-малкия брой знаци. Приложен към същия низ, този модел съвпада само с първата буква а.

"Неалчното" повторение не винаги дава очаквания резултат. Помислете за модела /a+b/, който съответства на едно или повече a, последвано от b. За низа "aaab" съответства на целия низ.

Сега нека проверим "не-алчната" версия на /a+?b/. Човек може да си помисли, че трябва да съвпада с a b, предшествано само от едно a. Ако се приложи към същия низ, се очаква "aaab" да съответства на единично a и последното b. Всъщност обаче целият низ съответства на този модел, както в случая с "алчната" версия. Това е така, защото търсенето на модел на регулярен израз се извършва чрез намиране на първата позиция в низа, от която става възможно съвпадението. Тъй като е възможно съвпадение, започващо от първия символ на низа, по-кратките съвпадения, започващи от следващите знаци, дори не се разглеждат.

Алтернативи, групиране и връзки

Граматиката на регулярните изрази включва специални знаци за дефиниране на алтернативи, групиране на подизрази и препратки към предишни подизрази. Символ на вертикална лента | служи за разделяне на алтернативи. Например, /ab|cd|ef/ съответства или на низа "ab", или на низа "cd", или на низа "ef", а моделът /\d(3)|(4)/ съответства на три цифри или четири малки букви букви .

Имайте предвид, че алтернативите се обработват отляво надясно, докато се намери съвпадение. Ако бъде намерено съвпадение с лявата алтернатива, дясната алтернатива се игнорира, дори ако може да се постигне "по-добро" съвпадение. Така че, когато /a|ab/ се ​​приложи към низа "ab", той ще съвпада само с първия знак.

Скобите имат множество значения в регулярните изрази. Един от тях е групирането на отделни елементи в един подизраз, така че елементите при използване на специалните знаци |, *, +, ? а други се третират като едно. Например, моделът /java(script)?/ съвпада с думата "java", последвана от незадължителната дума "script", а /(ab|cd)+|ef)/ съответства на низа "ef" или на един или повече повторения на едно от низовете "ab" или "cd".

Друга употреба на скоби в регулярните изрази е да се дефинират подмодели в рамките на шаблон. Когато в целевия низ се намери съвпадение на регулярен израз, частта от целевия низ, която съответства на всеки конкретен подмодел в скоби, може да бъде извлечена.

Да предположим, че искате да намерите една или повече малки букви, последвани от една или повече цифри. Можете да използвате шаблона /+\d+/ за това. Но да предположим също, че искаме само числата в края на всеки мач. Ако поставим тази част от шаблона в скоби (/+(\d+)/), тогава можем да извлечем числа от всички съвпадения, които намерим. Как се прави това ще бъде описано по-долу.

Свързано с това е друго използване на подизрази в скоби за препращане към подизрази от предишната част на същия регулярен израз. Това се постига чрез посочване на една или повече цифри след символа \. Числата се отнасят до позицията на подизраза в скоби в регулярния израз. Например, \1 се отнася до първия подизраз, а \3 се отнася до третия. Имайте предвид, че подизразите могат да бъдат вложени, така че позицията на лявата скоба се използва в броя. Например в следния регулярен израз препратката към вложения подизраз (скрипт) ще изглежда като \2:

/(ava(script)?)\sis\s(забавление\w*)/

Препратката към предишния подизраз не сочи към шаблона на този подизраз, а към намерения текст, който съответства на този шаблон. Следователно, препратките могат да се използват за налагане на ограничение, което избира части от низ, които съдържат точно същите символи. Например, следният регулярен израз съответства на нула или повече знака в единични или двойни кавички. Това обаче не изисква началните и затварящите кавички да съвпадат (тоест и двата кавички да са единични или двойни):

/[""][^""]*[""]/

Можем да изискваме цитати да съвпадат с тази справка:

Тук \1 съответства на съвпадението на първия подизраз. В този пример връзката налага ограничение, изискващо затварящата котировка да съвпада с началната. Този регулярен израз не позволява единични кавички в двойни кавички и обратно.

Възможно е също така да се групират елементи в регулярен израз, без да се създава номерирана препратка към тези елементи. Вместо просто да групирате елементи между (и) започвайте групата със знаци (?: и я завършвайте със знак). Помислете например за следния шаблон:

/(ava(?:script)?)\sis\s(забавление\w*)/

Тук подизразът (?:script) е необходим само за групиране, така че символът за повторение ? може да се приложи към групата. Тези модифицирани скоби не създават връзка, така че \2 в този регулярен израз се отнася до текст, който съответства на шаблона (забавно\w*).

Следната таблица изброява операторите за избор от алтернативи, групиране и препращане в регулярни изрази:

Знаците за регулярни изрази избират от алтернативи, групиране и JavaScript връзки
символ смисъл
| Алтернативен. Съвпада или с подизраза отляво или с подизраза отдясно.
(...) Групиране. Групира елементите в един обект, който може да се използва с *, +, ?, | и т.н. Също така запомня знаците, съответстващи на тази група, за използване в следващите връзки.
(?:...) Само групиране. Групира елементите заедно, но не помни знаците, съответстващи на тази група.
\ номер Съответства на същите знаци, които са открити при съпоставяне с номер на групата. Групите са подизрази в скоби (евентуално вложени). Номерата на групите се присвояват чрез преброяване на левите скоби отляво надясно. Групите, образувани с (?:) знаци, не са номерирани.

Посочване на позиция на съвпадение

Както беше описано по-рано, много елементи от регулярен израз съвпадат с един знак в низ. Например, \s съответства на един празен символ. Други елементи на регулярните изрази съответстват на позициите между знаците, а не на самите знаци. Например, \b съвпада с граница на думата - граница между \w (символ за ASCII текст) и \W (нетекстов знак) или граница между текстов символ на ASCII и началото или края на ред.

Елементи като \b не дефинират никакви знаци, които трябва да присъстват в съответстващия низ, но те дефинират валидни позиции за съвпадение. Тези елементи понякога се наричат ​​елементи за закотвяне на регулярен израз, тъй като те закотвят шаблона към определена позиция в низа. По-често от други се използват елементи за закотвяне като ^ и $, които закотвят шаблони съответно в началото и края на реда.

Например думата "JavaScript" на собствен ред може да бъде съпоставена с регулярния израз /^JavaScript$/. За да намерите една дума "Java" (а не префикс, например в думата "JavaScript"), можете да опитате да използвате шаблона /\sJava\s/, който изисква интервал преди и след думата.

Но това решение поражда два проблема. Първо, той ще намери думата "Java" само ако е заобиколена от интервали от двете страни и няма да я намери в началото или края на низа. Второ, когато този модел съвпада, низът, който връща, ще съдържа водещи и крайни интервали, което не е точно това, което искаме. Така че вместо шаблон, който съответства на символи за интервал \s, ще използваме шаблон (или котва), който съответства на границите на думите \b. Ще се получи следният израз: /\bJava\b/.

Закотвеният елемент \B съответства на позиция, която не е граница на думата. Тоест шаблонът /\Bcript/ ще съвпада с думите "JavaScript" и "postscript" и няма да съвпада с думите "script" или "Scripting".

Произволните регулярни изрази могат също да действат като условия на котва. Поставянето на израз между знаците (?= и) го превръща в предварително съвпадение за следващите знаци, като изисква тези знаци да съответстват на посочения шаблон, но не са включени в низа за съвпадение.

Например, за да съвпаднете с името на общ език за програмиране, последвано от двоеточие, можете да използвате израза /ava(script)?(?=\:)/. Този модел съвпада с думата "JavaScript" в низа "JavaScript: Окончателното ръководство", но няма да съвпада с думата "Java" в низа "Java in a Nutshell", защото не е последвана от двоеточие.

Ако въведете условието (?!, тогава това ще бъде отрицателен предварителен тест за следващите знаци, изискващ следните знаци да не съвпадат с посочения шаблон. Например шаблонът /Java(?!Script)(\w *)/ съвпада с поднизът "Java", последван от главна буква и произволен брой текстови знаци ASCII, при условие че поднизът "Java" не е последван от подниз "Script" Той съвпада с низа "JavaBeans", но не съвпада низът "Javanese", съответства на низа "JavaScrip", но няма да съответства на низовете "JavaScript" или "JavaScripter".

Таблицата по-долу изброява символите за закотвяне в регулярни изрази:

Котви за регулярни изрази
символ смисъл
^ Съвпада с началото на низов израз или началото на низ при многоредово търсене.
$ Съответства на края на низов израз или на края на низ при многоредово търсене.
\b Съвпада с граница на думата, т.е. съответства на позицията между символа \w и символа \W или между символа \w и началото или края на низа. (Обърнете внимание обаче, че [\b] съответства на символ за връщане назад.)
\B Отговаря на позиция, която не е граница на думите.
(?=p) Положителна предварителна проверка за следващите знаци. Изисква следващите знаци да съответстват на шаблона p, но не включва тези знаци в намерения низ.
(?! п) Отрицателна предварителна проверка за следващите знаци. Изисква следните знаци да не съвпадат с шаблона p.

Знамена

И един последен елемент от граматиката на регулярните изрази. Флаговете за регулярни изрази дефинират правила за съвпадение на шаблони от високо ниво. За разлика от останалата граматика на регулярните изрази, флаговете не са посочени между наклонената черта, а след втория. Езикът JavaScript поддържа три флага.

флаг иуказва, че търсенето на шаблон трябва да бъде независимо от главните букви и g флаг- че търсенето трябва да е глобално, т.е. всички съвпадения в низа трябва да бъдат намерени. знаме мизвършва търсене на шаблон в многоредов режим. Ако търсеният низов израз съдържа нови редове, тогава в този режим символите за закотвяне ^ и $, освен че съвпадат с началото и края на целия низов израз, съвпадат и с началото и края на всеки текстов ред. Например, шаблонът /java$/im съответства както на "java", така и на "Java\nis fun".

Тези знамена могат да се комбинират във всяка комбинация. Например, за да търсите първото появяване на думата "java" (или "Java", "JAVA" и т.н.) по начин, нечувствителен към малки и големи букви, можете да използвате регулярния израз /\bjava\b/ и И за да намерите всички срещания на тази дума в низ, можете да добавите флага g: /\bjava\b/gi.

Методи на низови класове за съвпадение на шаблони

До този момент обсъждахме граматиката на генерираните регулярни изрази, но не сме разгледали как тези регулярни изрази всъщност могат да се използват в JavaScript скриптове. В този раздел ще обсъдим методи на String обекта, които използват регулярни изрази за съвпадение на шаблони, както и за търсене и замяна. И тогава ще продължим да говорим за съвпадение на шаблони с регулярни изрази, като разгледаме обекта RegExp, неговите методи и свойства.

Низовете поддържат четири метода, използващи регулярни изрази. Най-простият от тях е методът Търсене(). Той приема регулярен израз като аргумент и връща или позицията на първия знак от намерения подниз, или -1, ако не е намерено съвпадение. Например следното повикване ще върне 4:

Varresult = "JavaScript".search(/script/i); // четири

Ако аргументът на метода search() не е регулярен израз, той първо се преобразува чрез предаването му на конструктора RegExp. Методът search() не поддържа глобални търсения и игнорира флага g в своя аргумент.

Метод замести()извършва операция за търсене и замяна. Той приема регулярен израз като свой първи аргумент и заместващ низ като втори. Методът търси низа, за който е извикан, за да съответства на посочения шаблон.

Ако регулярният израз съдържа флага g, методът replace() заменя всички намерени съвпадения със заместващия низ. В противен случай той заменя само първото намерено съвпадение. Ако първият аргумент на метода replace() е низ, а не регулярен израз, тогава методът извършва буквално търсене на низа, вместо да го преобразува в регулярен израз с помощта на конструктора RegExp() като search() метод прави.

Като пример можем да използваме метода replace(), за да изпишем еднакво с главни букви думата "JavaScript" за цял ред текст:

// Независимо от регистра на символите, ние заменяме думата в желания регистър var result = "javascript".replace(/JavaScript/ig, "JavaScript");

Методът replace() е по-мощен, отколкото този пример предполага. Припомнете си, че подизразите в скоби в рамките на регулярен израз са номерирани отляво надясно и че регулярният израз запомня текста, който съответства на всеки от подизразите. Ако заместващият низ съдържа знак $, последван от число, методът replace() заменя тези два знака с текста, който съответства на посочения подизраз. Това е много полезна функция. Можем да го използваме, например, за да заменим прави кавички в низ с типографски кавички, които имитират ASCII знаци:

// Цитатът е цитат, последван от произволен брой знаци // различни от кавички (ние ги помним), тези знаци // са последвани от друг цитат var quote = /"([^"]*)"/g; / / Заменете правите кавички с типографски и оставете "$1" непроменено // Цитирайте съдържанието, съхранявано в $1 var text = ""JavaScript" е интерпретиран език за програмиране."; var result = text.replace(quote, ""$1"") ; // "JavaScript" е интерпретиран език за програмиране.

Важно нещо, което трябва да се отбележи, е, че вторият аргумент на replace() може да бъде функция, която динамично изчислява заместващия низ.

Метод съвпада()е най-общият от методите на клас String, които използват регулярни изрази. Той приема регулярен израз като единствен аргумент (или преобразува аргумента си в регулярен израз, като го предава на конструктора RegExp()) и връща масив, съдържащ резултатите от търсенето. Ако флагът g е зададен в регулярния израз, методът връща масив от всички съвпадения, присъстващи в низа. Например:

// връща ["1", "2", "3"] var result = "1 плюс 2 е равно на 3".match(/\d+/g);

Ако регулярният израз не съдържа флага g, методът match() не извършва глобално търсене; просто търси първото съвпадение. Въпреки това match() връща масив дори когато методът не извършва глобално търсене. В този случай първият елемент от масива е намереният подниз, а всички останали елементи са подизрази на регулярния израз. Следователно, ако match() върне масив arr, тогава arr ще съдържа целия намерен низ, arr поднизът, съответстващ на първия подизраз, и т.н. Като направим паралел с метода replace(), можем да кажем, че arr[n] е изпълнен със съдържанието на $n.

Например, разгледайте следния код, който анализира URL адрес:

Var url = /(\w+):\/\/([\w.]+)\/(\S*)/; var text = "Посетете нашия сайт http://www..php"; var резултат = текстово съвпадение(url); if (резултат != null) ( var fullurl = резултат; // Съдържа "http://www..php" var protocol = резултат; // Съдържа "http" var host = резултат; // Съдържа "www..php ")

Обърнете внимание, че за регулярен израз, който няма зададен флаг за глобално търсене g, методът match() връща същата стойност като метода exec() на регулярния израз: върнатият масив има свойства на индекс и вход, както е описано в обсъждането на exec() по-долу.

Последният метод на String обекта, който използва регулярни изрази е раздели(). Този метод разделя низа, на който е извикан, на масив от поднизове, като използва аргумента като разделител. Например:

"123,456,789".split(","); // Връща ["123","456","789"]

Методът split() може също да приеме регулярен израз като аргумент. Това прави метода по-мощен. Например, можете да посочите разделител, който позволява произволен брой празни знаци от двете страни:

"1, 2, 3 , 4 , 5".split(/\s*,\s*/); // Връща ["1","2","3","4","5"]

Обект на Regexp

Както споменахме, регулярните изрази се представят като RegExp обекти. В допълнение към конструктора RegExp(), RegExp обектите поддържат три метода и няколко свойства.

Конструкторът RegExp() приема един или два низови аргумента и създава нов обект RegExp. Първият аргумент на конструктора е низ, съдържащ тялото на регулярния израз, т.е. текстът, който трябва да се появи между наклонените черти в литерала на регулярния израз. Обърнете внимание, че низовите литерали и регулярните изрази използват символа \ за означаване на escape последователности, така че когато предавате регулярен израз като низов литерал към конструктора RegExp(), трябва да замените всеки символ \ с двойка символи \\.

Вторият аргумент на RegExp() може да липсва. Ако е посочено, той посочва флаговете на регулярните изрази. Трябва да е един от знаците g, i, m или комбинация от тези знаци. Например:

// Намира всички петцифрени числа в низ. Забележка // използването на символи \\ в този пример var zipcode = new RegExp("\\d(5)", "g");

Конструкторът RegExp() е полезен, когато регулярен израз се генерира динамично и следователно не може да бъде представен с помощта на синтаксис на литерал на регулярен израз. Например, за да намерите низ, въведен от потребителя, трябва да създадете регулярен израз по време на изпълнение с помощта на RegExp().

Свойства на регулярни изрази

Всеки обект на RegExp има пет свойства. Имот източник- низ само за четене, съдържащ текста на регулярния израз. Имот глобалене булева стойност само за четене, която определя присъствието на флага g в регулярния израз. Имот ignoreCaseе булева стойност само за четене, която указва дали флагът i присъства в регулярния израз. Имот многоредове булева стойност само за четене, която указва дали флагът m присъства в регулярния израз. И последния имот lastIndexе цяло число за четене/запис. За шаблони с флага g това свойство съдържа номера на позицията в низа, от която следва да започне следващото търсене. Както е описано по-долу, той се използва от методите exec() и test().

Методи на RegExp

Обектите на RegExp дефинират два метода, които извършват съвпадение на шаблони; те се държат подобно на методите на клас String, описани по-горе. Основният метод на класа RegExp, използван за съвпадение на шаблони, е exec(). Той е подобен на споменатия метод String class match(), с изключение на това, че е метод на клас RegExp, който приема низ като аргумент, а не метод на клас String, който приема аргумент RegExp.

Методът exec() изпълнява регулярния израз за посочения низ, т.е. търси съвпадение в низ. Ако не бъде намерено съвпадение, методът връща null. Ако обаче бъде намерено съвпадение, той връща същия масив като масива, върнат от метода match() за търсене без флага g. Нулевият елемент на масива съдържа низа, който съответства на регулярния израз, а всички следващи елементи са поднизове, които съответстват на всички подизрази. Освен това имотът индекссъдържа номера на позицията на знака, с който започва съответният фрагмент, и свойството входсе отнася до търсения низ.

За разлика от match(), методът exec() връща масив, чиято структура не зависи от наличието на флага g в регулярния израз. Нека ви напомня, че при предаване на глобален регулярен израз, методът match() връща масив от намерени съвпадения. И exec() винаги връща едно съвпадение, но предоставя пълна информация за него. Когато exec() се извика върху регулярен израз, съдържащ флага g, методът задава свойството lastIndex на обекта на регулярния израз на номера на позицията на знака непосредствено след съвпадащия подниз.

Когато методът exec() бъде извикан за същия регулярен израз втори път, той започва да търси в позицията на символа, посочена в свойството lastIndex. Ако exec() не намери съвпадение, свойството lastIndex е настроено на 0. (Можете също да зададете lastIndex на нула по всяко време, което трябва да направите във всички случаи, когато търсенето завършва преди последното съвпадение в един ред да е било намерено и търсенето започва от различен низ със същия обект на RegExp.) Това специално поведение позволява на exec() да бъде извикан многократно, за да се итерират всички съвпадения на регулярни изрази в низ. Например:

Varpattern = /Java/g; var text = "JavaScript е по-забавен от Java!"; varresult; while((резултат = pattern.exec(text)) != null) ( console.log("Намерен "" + резултат + """ + " на позиция " + result.index + "; следващото търсене ще започне от " + шаблон .lastIndex); )

Друг метод на обекта RegExp - тест(), което е много по-просто от метода exec(). Той взема низ и връща true, ако низът съвпада с регулярния израз:

Varpattern = /java/i; pattern.test("JavaScript"); // Връщане на истина

Извикването на test() е еквивалентно на извикване на exec() връщайки true, ако exec() връща не-нула. Поради тази причина методът test() се държи точно като метода exec(), когато се извиква към глобален регулярен израз: той започва да търси посочения низ на позицията, посочена от свойството lastIndex, и ако намери съвпадение, задава свойството lastIndex към номера на позицията на знака директно след намереното съвпадение. Следователно, използвайки метода test(), можете също да формирате цикъл за обхождане на низ, както използвате метода exec().

Тази статия обхваща основите на използването на регулярен израз в Javascript.

Въведение

Какво е регулярен израз?

Редовният израз на JS е последователност от знаци, която формира правило за търсене. След това това правило може да се използва за търсене на текст, както и за замяната му. На практика регулярен израз може дори да се състои от един знак, но по-сложните модели за търсене са по-чести.

В Javascript регулярните изрази също са обекти. Това са модели, използвани за съпоставяне на поредици от знаци в низове. Те се използват в методите exec() и test() на обекта RegExp и в методите match() , replace(), search и split() на обекта String.

Пример

var pattern = /example/i

/example/i е регулярен израз. пример е шаблон ( да се използва при търсенето). i е модификатор, показващ чувствителността на малки и големи букви.

Изготвяне на регулярен израз

JS регулярните изрази се състоят от шаблон и модификатор. Синтаксисът ще бъде нещо като това:

/шаблон/модификатори;

Шаблонът дефинира правилото за търсене. Състои се от прости знаци като /abc/ или комбинация от прости и специални знаци: /abc/ или /Chapter (d+).d/ .

Таблица с шаблони

Модификаторите ви позволяват да правите заявките чувствителни към главни букви, глобални и т.н. Те се използват за извършване на търсения, чувствителни към малки и големи букви, както и глобални търсения.

Таблица с модификатори

Сега сме готови да приложим регулярни изрази на JS. Има два основни начина да направите това: използване на обект на регулярен израз или използване на регулярен израз в низ.

Използване на обекта с регулярни изрази

Създайте обект на регулярен израз

Този обект описва символен шаблон. Използва се за съвпадение на шаблони. Има два начина за конструиране на обект на регулярен израз.

Метод 1: Използване на литерал на регулярен израз, който се състои от шаблон, затворен в наклонени черти, като този:

varreg = /ab+c/;

Литералите на регулярните изрази задействат предварителна компилация на регулярен израз, когато скриптът се анализира. Ако регулярният израз е постоянен, използвайте го, за да увеличите производителността.

Метод 2: Чрез извикване на функцията конструктор на обекта RegExp, например:

varreg = new RegExp("ab+c");

Използването на конструктора ви позволява да компилирате регулярния израз на JS по време на скрипт. Използвайте този метод, ако регулярният израз ще се промени или не знаете шаблона предварително. Например, ако получите информация от потребител, който въведе заявка за търсене.

Обектни методи с регулярни изрази

Нека се запознаем с няколко често срещани метода на обекта на регулярния израз:

  • компилиране() ( оттеглено във версия 1.5) - компилира регулярен израз;
  • exec() - Извършва съвпадение на низ. Връща първото съвпадение;
  • test() - извършва съвпадение на низ. Връща true или false ;
  • toString() - връща низовата стойност на регулярния израз.

Примери

Използване на test()

Методът test() е регулярен израз на обекта RegExp. Той търси низ от шаблон и връща true или false в зависимост от резултата. Следващият пример за регулярен израз на JS показва как се търси низ за символа „ д”:

varpatt = /e/; patt.test("Най-добрите неща на света са безплатни!");

Тъй като тук в реда има „ д“, резултатът от този код ще бъде истина.

Регулярните изрази изобщо не трябва да се поставят в променлива. Същата заявка може да се направи в един ред:

/e/.test("Най-добрите неща на света са безплатни!");

Използване на exec()

Той търси низа според даденото правило за търсене и връща намерения текст. Ако не бяха намерени съвпадения, тогава резултатът е нулев.

Нека разгледаме метода в действие, като използваме примера на същия символ „ д”:

/e/.exec("Най-добрите неща на света са безплатни!");

Тъй като редът съдържа " д”, резултатът от този код ще бъде .e .

Прилагане на регулярен израз към низ

В Javascript тези изрази могат да се използват и с два метода на String обекта: search() и replace() . Те са необходими за извършване на търсене и замяна в текст.

  • метод search() - използва израз за намиране на съвпадение и връща информация за местоположението на съвпадението;
  • Методът replace() връща модифициран низ със заменения шаблон.

Примери

Използване на регулярен израз на JS за търсене на фразата, чувствително към главни и малки букви w3schools" в редица:

varstr = "Посетете W3Schools"; var n = str.search(/w3schools/i);

Резултатът в n ще бъде 6.

Методът за търсене също приема низ като аргумент. Аргументът низ ще бъде преобразуван в регулярен израз:

Използване на низ за търсене на фразата „ W3schools" в редица.

Регулярни изрази ( Regexp) е много ефективен начин за работа с низове.

Чрез съставянето на регулярен израз с помощта на специален синтаксис можете:

  • текст за търсенев редица
  • заменете поднизоветев редица
  • извличане на информацияот низ

Почти всички езици за програмиране имат регулярни изрази. Има леки разлики в изпълнението, но общите концепции важат почти навсякъде.

Регулярните изрази датират от 50-те години на миналия век, когато са формализирани като концептуален модел за търсене на алгоритми за обработка на низове.

Регулярните изрази, внедрени в UNIX, като grep, sed и популярни текстови редактори, започнаха да набират популярност и бяха добавени към езика за програмиране Perl, а по-късно и към много други езици.

JavaScript, заедно с Perl, е един от езиците за програмиране, който има поддръжка на регулярни изрази, вградена направо в езика.

Трудно, но полезно

За начинаещи регулярните изрази могат да изглеждат като абсолютна глупост и често дори за професионални разработчици, ако не инвестирате необходимото време, за да ги разберете.

Регулярни изрази трудно се пише, трудно се четеи трудно се поддържа/променя.

Но понякога регулярните изрази са единственият разумен начинизвършват някакъв вид манипулация на низове, така че те са много ценен инструмент.

Това ръководство има за цел да ви даде някакво основно разбиране за регулярните изрази в JavaScript по възможно най-лесния начин и да предостави информация как да четете и създавате регулярни изрази.

Основното правило е това простите регулярни изрази са лесни за четене и писане, докато сложните регулярни изрази могат бързо да се превърнат в бъркотияако не разбирате основите в дълбочина.

Как изглеждат регулярните изрази

В JavaScript регулярният израз е обект, който може да бъде дефиниран по два начина.

Първият начин е да създадете нов обект на RegExpс помощта на конструктора:

Const re1 = new RegExp("хей")

Вторият начин е да се използва литерали на регулярни изрази:

Const re1 = /хей/

Знаете ли какво е JavaScript? обектни литералии литерали на масива? То също има литерали на регулярни изрази.

В примера по-горе се нарича hey шаблон. В буквална форма е между две наклонени черти, но в случай на конструктор на обект не е така.

Това е първата важна разлика между двата начина за дефиниране на регулярни изрази, останалите ще видим по-късно.

Как работят те?

Регулярният израз, който дефинирахме по-горе като re1, е много прост. Той търси низа hey без никакви ограничения: низът може да съдържа много текст, а думата hey е някъде по средата и регулярният израз ще работи. Низът може да съдържа само думата hey и регулярният израз ще работи отново.

Това е доста просто.

Можете да опитате да тествате регулярния израз с метода RegExp.test(String), който връща булева стойност:

Re1.test("hey") // ✅ re1.test("blablabla хей blablabla") // ✅ re1.test("he") // ❌ re1.test("blablabla") // ❌

В примера по-горе току-що проверихме дали „хей“ съвпада с шаблона на регулярния израз, съхранен в re1.

Лесно е като черупката на круши, но вече знаете много за регулярните изрази.

Закотвяне

/Хей/

ще работи независимо къде е hey в низа.

Ако искате да намерите редове, които започват с hey , използвайте оператора ^:

/^хей/.test("хей") // ✅ /^хей/.test("бла хей") // ❌

Ако искате да намерите редове, които завършват на hey, използвайте оператора $:

/hey$/.test("hey") // ✅ /hey$/.test("bla hey") // ✅ /hey$/.test("хей ти") // ❌

Като комбинирате двете предишни твърдения, можете да намерите ред, който точно съвпада hey:

/^хей$/.test("хей") // ✅

За да намерите низ, който започва с един подниз и завършва с друг подниз, можете да използвате .*, който ще съответства на всеки знак, повторен 0 или повече пъти:

/^hey.*joe$/.test("hey joe") // ✅ /^hey.*joe$/.test("heyjoe") // ✅ /^hey.*joe$/.test("хей как си Джо") // ✅ /^хей.*joe$/.test("хей, Джо!") // ❌

Намиране на елементи по диапазон

Вместо да търсите конкретен низ, можете да посочите диапазон от знаци, както следва:

// // a, b, c, ... , x, y, z // // A, B, C, ... , X, Y, Z // // a, b, c // / / 0, 1, 2, 3, ... , 8, 9

Тези регулярни изрази търсят низове, които съдържат поне един знак от избрания диапазон:

//.test("a") // ✅ //.test("1") // ❌ //.test("A") // ❌ //.test("d") // ❌ // .test("dc") // ✅

Диапазоните могат да се комбинират:

// //.test("a") // ✅ //.test("1") // ✅ //.test("A") // ✅

Намиране на множество съвпадения на елемент на диапазон

Можете да проверите дали низ съдържа само един знак от диапазон, като използвате знака -:

/^$/ /^$/.test("A") // ✅ /^$/.test("Ab") // ❌

Обръщане на шаблона

Знакът ^ в началото на шаблон го закотвя към началото на реда.

Използването на този знак в диапазон инвертира диапазона, така че:

/[^A-Za-z0-9]/.test("a") // ❌ /[^A-Za-z0-9]/.test("1") // ❌ /[^A-Za -z0-9]/.test("A") // ❌ /[^A-Za-z0-9]/.test("@") // ✅

Метазнаци

  • \d съответства на произволно число, еквивалентно на
  • \D съответства на всеки знак, който не е число, еквивалентно на [^0-9]
  • \w съответства на всеки буквено-цифров знак, еквивалентен на
  • \W съответства на всеки знак, който не е буквено-цифрова стойност, еквивалентна на [^A-Za-z0-9]
  • \s съответства на всеки символ на интервал: интервал, табулатор, нов ред и интервали Unicode
  • \S съответства на всеки знак, който не е интервал
  • \0 съответства на нула
  • \n съответства на символа за нов ред
  • \t съвпада с табулаторен знак
  • \uXXXX съответства на символа на Unicode с код XXXX (изисква флага u)
  • . съответства на всеки знак с изключение на нов ред (като \n) (освен ако не използвате флага s, обяснено по-късно)
  • [^] съответства на всеки знак, включително символа за нов ред. Полезно при работа с многоредови низове

Избор в регулярни изрази

Ако искате да изберете един илидруг ред, използвайте | .

/hey|ho/.test("hey") // ✅ /hey|ho/.test("ho") // ✅

Квантори

Представете си, че имате регулярен израз, който проверява дали низ съдържа само една цифра:

можеш да използваш квантор? , което ще направи този знак незадължителен. В нашия случай числото трябва да се появи 0 или 1 пъти:

но какво ще стане, ако искаме регулярният израз да съвпада с множество цифри?

Можете да го направите по 4 начина, като използвате + , * , (n) и (n,m) .

+

Съответства на един или повече (>=1) елемента:

/^\d+$/ /^\d+$/.test("12") // ✅ /^\d+$/.test("14") // ✅ /^\d+$/.test("144343" ) // ✅ /^\d+$/.test("") // ❌ /^\d+$/.test("1a") // ❌

*

Съответства на 0 или повече (>=0) елемента:

/^\d+$/ /^\d*$/.test("12") // ✅ /^\d*$/.test("14") // ✅ /^\d*$/.test( "144343") // ✅ /^\d*$/.test("") // ✅ /^\d*$/.test("1a") // ❌

(н)

Съвпада точно с n брой елементи:

/^\d(3)$/ /^\d(3)$/.test("123") // ✅ /^\d(3)$/.test("12") // ❌ /^\ d(3)$/.test("1234") // ❌ /^(3)$/.test("Abc") // ✅

(n,m)

Съответства на диапазон от n до m елементи:

/^\d(3,5)$/ /^\d(3,5)$/.test("123") // ✅ /^\d(3,5)$/.test("1234") // ✅ /^\d(3,5)$/.test("12345") // ✅ /^\d(3,5)$/.test("123456") // ❌

m може да бъде пропуснато и второто ограничение да остане неограничено, така че да има поне n елемента:

/^\d(3,)$/ /^\d(3,)$/.test("12") // ❌ /^\d(3,)$/.test("123") // ✅ /^\d(3,)$/.test("12345") // ✅ /^\d(3,)$/.test("123456789") // ✅

Елементи по избор

Героят, следващ елемента? , ще го направи по избор:

/^\d(3)\w?$/ /^\d(3)\w?$/.test("123") // ✅ /^\d(3)\w?$/.test(" 123a") // ✅ /^\d(3)\w?$/.test("123ab") // ❌

Групи

С помощта на скоби можете да създавате групи от знаци (...) .

Примерът по-долу търси точно съвпадение от 3 цифри, последвани от един или повече буквено-цифрови знака:

/^(\d(3))(\w+)$/ /^(\d(3))(\w+)$/.test("123") // ❌ /^(\d(3))( \w+)$/.test("123s") // ✅ /^(\d(3))(\w+)$/.test("123something") // ✅ /^(\d(3))( \w+)$/.test("1234") // ✅

Повтарящите се знаци, които се появяват след скобата за затваряне на групата, се отнасят за цялата група:

/^(\d(2))+$/ /^(\d(2))+$/.test("12") // ✅ /^(\d(2))+$/.test(" 123") // ❌ /^(\d(2))+$/.test("1234") // ✅

Улавяне на групи

Досега видяхме как да тестваме низове и да видим дали те съдържат определен модел.

Страхотна функция на регулярните изрази е, че можете заснемане на определени части от низи ги добавете към масив.

Можете да направите това с групи, по-точно с улавяне на групи.

По подразбиране групите се улавят по този начин. Сега, вместо да използваме RegExp.test(String) , който просто връща булев, ще използваме един от следните методи:

  • Съвпадение на низ (RegExp)
  • RegExp.exec(низ)

Те са абсолютно еднакви и връщат масив с низа, който се тества като първи елемент, а в останалите елементи има съвпадение за всяка намерена група.

Ако не бъде намерено съвпадение, тогава той връща null.

"123s".match(/^(\d(3))(\w+)$/) //Масив [ "123s", "123", "123s" ] /^(\d(3))(\w+ )$/.exec("123s") //Масив [ "123s", "123", "s" ] "hey".match(/(hey|ho)/) //Масив [ "хей", "хей " ] /(хей|хо)/.exec("хей") //Масив [ "хей", "хей" ] /(хей|хо)/.exec("ха!") //null

Когато група съвпада няколко пъти, тогава към върнатия масив ще бъде добавена само последната намерена стойност.

"123456789".match(/(\d)+/) //Масив [ "123456789", "9" ]

Групи по избор

Заснемането на групи може да се направи по избор с (...)? . Ако нищо не бъде намерено, тогава към върнатия масив ще бъде добавен недефиниран елемент:

/^(\d(3))(\s)?(\w+)$/.exec("123 s") //Масив [ "123 s", "123", " ", "s" ] /^ (\d(3))(\s)?(\w+)$/.exec("123s") //Масив [ "123s", "123", undefined, "s" ]

Линк към намерената група

На всяка намерена група се присвоява номер. $1 се отнася до първия елемент, $2 до втория и т.н. Това е полезно, когато говорим за подмяна на част от низ.

Заснемане на имена група

Това е нова функция в ES2018.

Можете да присвоите име на група вместо само слот в върнатия масив:

Const re = /(? \d(4))-(? \d(2))-(? \d(2))/ const result = re.exec("2015-01-02") // result.groups.year === "2015"; // result.groups.month === "01"; // result.groups.day === "02";

Използване на match и exec без групи

Има разлика при използване на match и exec без групи: първият елемент от масива няма да съдържа напълно намерен низ, а директно съвпадение:

/хей|хо/.exec("хей") // [ "хей" ] /(хей).(хо)/.exec("хей, хо") // [ "хей, хо", "хей", "хо "]

Неулавящи групи

Тъй като групите могат да се заснемат по подразбиране, имаме нужда от начин да игнорираме някои от групите в върнатия масив. Това е възможно с неулавяеми групи, които започват с (?:...) .

"123s".match(/^(\d(3))(?:\s)(\w+)$/) // null "123 s".match(/^(\d(3))(?: \s)(\w+)$/) // Масив [ "123 s", "123", "s" ]

Знамена

Можете да използвате следните флагове за всеки регулярен израз:

  • g: търси съвпадения в световен мащаб
  • i: прави регулярния израз нечувствителен към малките букви
  • m: Активира многоредов режим. В този режим ^ и $ съответстват на началото и края на целия низ. Без този флаг, с многоредови низове, те съвпадат с началото и края на всеки ред.
  • u: Активира поддръжка на Unicode (добавено в ES6/ES2015)
  • s: (ново в ES2018) съкратено за "единична линия", позволява. съвпадат знаци за нов ред

Флаговете могат да се комбинират и също така се добавят в края на низа на литерала:

/hey/ig.test("HEy") // ✅

или се предава като втори параметър на конструктора на обекта RegExp:

Нов RegExp("hey", "ig").test("HEy") // ✅

Проверка на регулярни изрази

Можете да проверите свойствата на регулярните изрази:

  • източник - шаблонен низ
  • multiline - true, ако е зададен флагът m
  • global - вярно, ако е зададен флагът g
  • ignoreCase - вярно, ако е зададен флагът i
  • lastIndex
/^(\w(3))$/i.source //"^(\\d(3))(\\w+)$" /^(\w(3))$/i.multiline //false /^(\w(3))$/i.lastIndex //0 /^(\w(3))$/i.ignoreCase //true /^(\w(3))$/i.global // фалшиво

Екраниране

Специални символи:

Това са специални знаци, тъй като те са контролни знаци при съставянето на шаблони на регулярни изрази, така че ако искате да ги използвате за съвпадение в рамките на шаблон, трябва да ги избягате със знак за обратна наклонена черта:

/^\\$/ /^\^$/ // /^\^$/.test("^") ✅ /^\$$/ // /^\$$/.test("$") ✅

Граници на редове

\b и \B ви позволяват да определите дали низ е в началото или в края на дума:

  • \b съвпада, ако наборът от знаци е в началото или в края на дума
  • \B съвпада, ако наборът от знаци не е в началото или в края на дума

"Видях мечка".match(/\bbear/) //Масив ["bear"] "Видях мечка".match(/\bbear/) //Масив ["bear"] "Видях мечка" .match(/\bbear\b/) //null "cool_bear".match(/\bbear\b/) //null

Замяна с регулярни изрази

Вече видяхме как да проверяваме низовете спрямо шаблон.

Видяхме също как можете да извлечете част от низовете, които съответстват на шаблона, в масив.

Сега нека да разгледаме как заменете части от низвъз основа на шаблон.

Обектът String в JavaScript има метод replace(), който може да се използва без регулярни изрази една замянав редица:

"Здравей свят!".replace("свят", "куче") //Здравей куче! "Моето куче е добро куче!".replace("куче", "котка") //Моята котка е добро куче!

Този метод може също да приеме регулярен израз като аргумент:

"Здравей свят!".replace(/world/, "куче") //Здравей куче!

Използването на флага g е единствения начинзаменете множеството срещания в низ с ванилен JavaScript:

"Моето куче е добро куче!".replace(/dog/g, "cat") //Моята котка е добра котка!

Групите ни позволяват да правим повече фантастични неща, да разменяме части от редове:

"Здравей, свят!".replace(/(\w+), (\w+)!/, "$2: $1!!!") // "свят: Здравей!!!"

Вместо низ можете да използвате функция, за да правите още по-интересни неща. Ще му бъдат предадени редица аргументи, като тези, върнати от методите String.match(RegExp) или RegExp.exec(String), където броят на аргументите зависи от броя на групите:

"Здравей, свят!".replace(/(\w+), (\w+)!/, (matchedString, first, second) => ( console.log(first); console.log(second); return `$( second.toUpperCase()): $(първо)!!!` )) //"СВЯТ: Здравейте!!!"

Алчност

Регулярните изрази се извикват алченпо подразбиране.

Какво означава?

Вземете за пример този регулярен израз:

/\$(.+)\s?/

Предполага се, че трябва да извлечем сумата в долари от низа:

/\$(.+)\s?/.exec("Това струва $100") //0

но какво, ако имаме повече думи след числото, това е разсейващо

/\$(.+)\s?/.exec("Това струва $100 и е по-малко от $200") //100 и е по-малко от $200

Защо? Тъй като регулярният израз след знака $ съвпада с всеки знак .+ и не спира, докато не достигне края на реда. След това спира, защото \s? прави крайното пространство по избор.

За да коригираме това, трябва да посочим, че регулярният израз трябва да бъде мързеливи намерете най-малкия брой съвпадения. Можем ли да направим това със символ? след квантора:

/\$(.+?)\s/.exec("Това струва $100 и е по-малко от $200") //100

Значи символ? може да означава различни неща в зависимост от позицията си, така че може да бъде както количествен, така и индикатор мързеливрежим.

Предишно: съпоставете низ в зависимост от това, което следва

Използвайте ?=, за да съпоставите низ, последван от конкретен подниз

/Roger(?=Waters)/ /Roger(?= Waters)/.test("Roger is my dog") //false /Roger(?= Waters)/.test("Roger is my dog ​​and Roger Waters е известен музикант") //вярно

Извършва обратната операция и намира съвпадения в реда, след което непоследван от конкретен подниз:

/Роджър(?!Уотърс)/ /Роджър(?! Уотърс)/.test("Роджър е моето куче") //true /Роджър(?! Уотърс)/.test("Роджър е моето куче и Роджър Уотърс") е известен музикант") //false

Ретроспективно: съпоставете низ в зависимост от това, което идва преди него

Това е нова функция в ES2018.

Прегледът напред използва символа ?=. Ретроспективни употреби?<= :

/(?<=Roger) Waters/ /(?<=Roger) Waters/.test("Pink Waters is my dog") //false /(?<=Roger) Waters/.test("Roger is my dog and Roger Waters is a famous musician") //true

Използва ли ретроспективната инверсия?

/(?

Регулярни изрази и Unicode

Флагът u е необходим при работа с низове в Unicode, особено когато може да е необходимо да се обработват низове в астрални равнини, които не са включени в първите 1600 символа Unicode.

Например емоджи, но само те.

/^.$/.test("a") // ✅ /^.$/.test("?") // ❌ /^.$/u.test("?") // ✅

Затова винаги използвайте флага u.

Unicode, подобно на обикновените знаци, може да обработва диапазони:

//.test("a") // ✅ //.test("1") // ✅ /[?-?]/u.test("?") // ✅ /[?-?]/u .test("?") // ❌

JavaScript проверява вътрешните кодове на представяне, затова ли?< ? < ? на самом деле \u1F436 < \u1F43A < \u1F98A . Посмотрите полный список эмодзи чтобы увидеть коды и узнать их порядок.

Екраниране на свойствата на Unicode

Както казахме по-горе, в модел на регулярни изрази можете да използвате \d за съвпадение на всяка цифра, \s за съвпадение на всеки знак с изключение на интервал, \w за съвпадение на всеки буквено-цифров знак и т.н.

Ескейпирането на свойства на Unicode е функция на ES2018, която добавя много готина функция, като разширява тази концепция до всички символи на Unicode и добавя \p() и \P() .

Всеки Unicode символ има набор от свойства. Например, Script дефинира езиково семейство, ASCII е булева стойност, която е вярна за ASCII знаци и т.н. Можете да поставите това свойство в къдрави скоби и регулярният израз ще провери дали стойността му е вярна:

/^\p(ASCII)+$/u.test("abc") // ✅ /^\p(ASCII)+$/u.test(" [защитен с имейл]") // ✅ /^\p(ASCII)+$/u.test("ABC?") // ❌

ASCII_Hex_Digit е друго булево свойство, което проверява дали низ съдържа само валидни шестнадесетични цифри:

/^\p(ASCII_Hex_Digit)+$/u.test("0123456789ABCDEF") //✅ /^\p(ASCII_Hex_Digit)+$/u.test("h")

Има много други булеви свойства, които можете да проверите само като добавите името им в къдрави скоби, включително Uppercase , Lowercase , White_Space , Alphabetic , Emoji и други:

/^\p(малки букви)$/u.test("h") // ✅ /^\p(Горни букви)$/u.test("H") // ✅ /^\p(Emoji)+$/ u.test("H") // ❌ /^\p(Emoji)+$/u.test("??") // ✅

В допълнение към тези двоични свойства, можете да тествате всяко свойство на символ в Unicode, за да съответства на конкретна стойност. В примера по-долу проверявам дали низът е написан на гръцката или латинската азбука:

/^\p(Script=Greek)+$/u.test("ελληνικά") // ✅ /^\p(Script=Latin)+$/u.test("Hey") // ✅

Примери

Извличане на число от низ

Да предположим, че има низ, съдържащ само едно число, което трябва да бъде извлечено. /\d+/ трябва да направи това:

"Test 123123329".match(/\d+/) // Масив [ "123123329" ]

Търсене на имейл адрес:

Най-простият подход е да проверите за символи, които не са празни интервали преди и след знака @, като използвате \S:

/(\S+)@(\S+)\.(\S+)/ /(\S+)@(\S+)\.(\S+)/.exec(" [защитен с имейл]") //["[защитен с имейл]", "copesc", "gmail", "com"]

Това обаче е опростен пример, тъй като включва много невалидни имейл адреси.

Улавяне на текст между двойни кавички

Нека си представим, че имате низ, който съдържа текст, затворен в двойни кавички и трябва да извлечете този текст.

Най-добрият начин да направите това е да използвате групово улавяне, защото знаем, че нашето съвпадение трябва да започва и да завършва с „ , за да можем лесно да персонализираме шаблона, но също така искаме да премахнем тези кавички от резултата.

В резултат ще намерим това, от което се нуждаем:

Const hello = "Здравей "хубаво цвете"" const result = /"([^"]*)"/.exec(hello) //Масив [ "\"хубаво цвете\"", "хубаво цвете" ]

Получаване на съдържание от HTML маркер

Например, вземете съдържанието от маркера span, като същевременно разрешите произволен брой аргументи за маркера:

/]*>(.*?)<\/span>/ /]*>(.*?)<\/span>/.exec("test") // null / ]*>(.*?)<\/span>/.exec("test") // ["тест", "тест"] / ]*>(.*?)<\/span>/.exec(" тест") // ["тест", "тест"]

Синтаксисът на регулярните изрази е доста сложен и изисква сериозни усилия за научаване. Най-доброто ръководство за регулярни изрази днес е Регулярните изрази на Дж. Фридъл, които, по думите на автора, „се научават да мислят в термините на регулярни изрази“.

Основни понятия

Редовен израз- инструмент за обработка на низове или поредица от знаци, който дефинира текстов шаблон.

Модификатор- е за "инструктиране" на регулярен израз.

Метазнаци- специални символи, които служат като команди на езика на регулярните изрази.

Регулярният израз е зададен като обикновена променлива, използва се само наклонена черта вместо кавички, например: var reg=/regexp/

Под най-простите шаблони имаме предвид онези шаблони, които не се нуждаят от специални знаци.

Да предположим, че нашата задача е да заменим всички букви "r" (малки и главни) с латинската главна буква "R" във фразата Регулярни изрази.

Създайте шаблон var reg=/r/и използвайки метода замениизпълняваме плановете си

В резултат на това получаваме линията - Регулярни изрази, замяната е извършена само при първото появяване на буквата "r", като се отчита малки и големи букви.

Но този резултат не отговаря на условията на нашия проблем... Тук имаме нужда модификатори"g" и "i", които могат да се използват поотделно или заедно. Тези модификатори се поставят в края на шаблона за регулярни изрази, след наклонената черта и имат следните значения:

модификатор"g" - задава търсенето в низа като "глобално", т.е. в нашия случай замяната ще се случи за всички поява на буквата "p". Сега шаблонът изглежда така: var reg=/r/g, замествайки го в нашия код

вземи струната - Регулярни изрази.

"i" модификатор- настройва търсенето в низа без значение от главните букви, като добави този модификатор към нашия шаблон var reg=/p/gi, след като изпълним скрипта, ще получим желания резултат от нашата задача - Регулярни изрази.

Специални знаци (метазнаци)

Метазнаците определят типа на символа на низа за търсене, начина, по който търсеният низ е заобиколен в текста, както и броя на знаците от конкретен тип в сканирания текст. Следователно метазнаците могат да бъдат разделени на три групи:

  • Съвпадение на метасимволи.
  • Количествени метазнаци.
  • Позициониране на метасимволи.

Съвпадение на метасимволи

смисъл

Описание

граница на думите

определя условието, при което шаблонът трябва да бъде изпълнен в началото или края на дума

/\ber/съвпада с грешка, не съвпада с геройили с играч
/е/съвпада с играч, не съвпада с геройили с грешка
/\ber\b/не съвпада с геройили с играчили с грешка, може само да съвпада ер

нито дума граница

определя условие, при което шаблонът не се изпълнява в началото или в края на дума

/\ber/съвпада с геройили с играч, не съвпада с грешка
/er\B/съвпада с грешкаили с играч, не съвпада с герой
/\Бер\Б/съвпада с герой, не съвпада с играчили с грешка

цифра от 0 до 9

/\d\d\d\d/съвпада с всяко четирицифрено число

/\D\D\D\D/не съвпада с 2005 или 05.gили №126 и т.н.

един празен знак

съответства на символ за интервал

\над\сбайт\съвпада само с над байт

единичен непразен знак

всеки един знак с изключение на интервал

\over\Sbyte\съвпада с над байтили с over_byte, не съвпада с над байтили над-байт

буква, цифра или долна черта

/A\w/съвпада с A1или с АБ, не съвпада с A+

не буква, цифра или долна черта

/A\W/не съвпада с A1или с АБ, съвпада с A+

всеки герой

всякакви знаци, букви, цифри и т.н.

/.../ съответства на всеки три знака ABCили [защитен с имейл] или 1 кв

набор от символи

определя условие, при което шаблонът трябва да бъде изпълнен за всяко съвпадение на знаци, затворени в квадратни скоби

/WERTY/съвпада с qwerty, С АВЕРТИ

набор от невходящи символи

определя условие, при което шаблонът не трябва да се изпълнява за съвпадение на знаци, затворени в квадратни скоби

/[^QA]WERTY/не съвпада с qwerty, С АВЕРТИ

Знаците, показани в таблицата "Метазнаци за съвпадение", не трябва да се бъркат с последователността от escape знаци, използвани в низовете, като \\t - таблица, \\n - нов ред и т.н.

Количествени метасимволи

Брой съвпадения

Нула или повече пъти

/Ja*script/съвпада с JavaScriptили с JavaScriptили с JavaScript, не съвпада с jovascript

Нула или един път

/javascript/съвпада само с JavaScriptили с JavaScript

Един или повече пъти

/javascript/съвпада с JavaScriptили с JavaScriptили с JavaScript, не съвпада с JavaScript

точно n пъти

/Ja(2)скрипт/съвпада само с JavaScript

n или повече пъти

/Ja(2,)script/съвпада с JavaScriptили с JavaScript, не съвпада с JavaScriptили с JavaScript

най-малко n пъти, но не повече от m пъти

/Ja(2,3)script/съвпада само с JavaScriptили с JavaScript

Всеки знак, изброен в таблицата с количествени метасимволи, се отнася за предходния знак или метазнак в регулярния израз.

Позициониране на метасимволи

Последният набор от метасимволи е предназначен да посочи къде да търсим (ако има значение) подниз в началото на низа или в края.

Някои методи за работа с шаблони

замени- вече използвахме този метод в самото начало на статията, той е предназначен за търсене на извадка и замяна на намерения подниз с нов подниз.

exec- този метод извършва съвпадение на низове спрямо шаблона, даден от шаблона. Ако съвпадението на шаблона не успее, тогава се връща null. В противен случай резултатът е масив от поднизове, които съответстват на дадения модел. /*Първият елемент от масива ще бъде равен на оригиналния низ, който отговаря на дадения шаблон*/

например:

в резултат получаваме четири реда:
Дата на раждане: 15.09.1980г
Рожден ден: 15
Месец на раждане: 09
Година на раждане: 1980г

Заключение

Статията не показва всички характеристики и прелести на регулярните изрази, за по-задълбочено проучване на този въпрос ви съветвам да изучите обекта RegExp. Искам също така да обърна внимание на факта, че синтаксисът на регулярните изрази не се различава както в JavaScript, така и в PHP. Например, за да проверите правилността на въвеждане на имейл, регулярен израз, какво за JavaScript, какво за PHP, ще изглежда по същия начин /[защитен с имейл]+.(2,3)/i.

Хареса ли ви статията? Сподели с приятели!