Verificarea potrivirii expresiilor regulate javascript. Verificare regExp - testare e-mail. Paranteze în expresiile regulate

În JavaScript expresii regulate sunt reprezentate de obiecte RegExp. Obiectele RegExp pot fi create folosind constructorul RegExp(), dar mai des sunt create folosind o sintaxă literală specială. La fel cum literalele șir sunt specificate ca caractere cuprinse între ghilimele, literalele expresii regulate sunt specificate ca caractere incluse într-o pereche de caractere bară oblică / .

/pattern/flags new RegExp(„model”[, opțiuni de căutare])

pattern este o expresie regulată de căutat (mai multe despre înlocuire mai târziu), iar flags este un șir de orice combinație de caractere g( căutare globală), i (cazul nu este important) și m (căutare multilinie). Prima metodă este folosită des, a doua - uneori. De exemplu, două astfel de apeluri sunt echivalente.

Opțiuni de căutare

Când creăm o expresie regulată, putem specifica opțiuni suplimentare căutare

Caractere din expresiile regulate JavaScript Corespondență simbol
Caractere alfanumericeCorespunde lor înșiși
\0 Caracter NUL (\u0000)
\tFilă (\u0009)
\nFlux de linie (\u000A)
\vFilă verticală (\u000B)
\fTraducerea paginii (\u000C)
\rRetur transport (\u000D)
\xnnset de caractere latine număr hexazecimal nn; de exemplu, \x0A este același cu \n
\uxxxxCaracter Unicode specificat de numărul hexazecimal xxxx; de exemplu, \u0009 este același cu \t
\cXCaracterul de control „X”, de exemplu, secvența \cJ este echivalentă cu caracterul newline \n
\ Pentru personajele obișnuite - le face speciale. De exemplu, expresia /s/ caută pur și simplu caracterul „s”. Și dacă puneți \ înainte de s, atunci /\s/ indică deja un caracter de spațiu Și invers, dacă caracterul este special, de exemplu *, atunci \ îl va face doar un caracter „asterisc” obișnuit. De exemplu, /a*/ caută 0 sau mai multe caractere consecutive „a”. Pentru a găsi un cu asterisc „a*” - pune \ în fața specialului. simbol: /a\*/ .
^ Indică începutul datelor de intrare. Dacă indicatorul de căutare pe mai multe linii ("m") este setat, se va declanșa și la începutul unei noi linii. De exemplu, /^A/ nu va găsi "A" în "un A", dar va găsi primul „A” în „An A”.
$ Indică sfârșitul datelor de intrare. Dacă este setat indicatorul de căutare pe mai multe linii, va funcționa și la sfârșitul liniei. De exemplu, /t$/ nu va găsi „t” în „eater”, dar îl va găsi în „eat”.
* Indică repetarea de 0 sau de mai multe ori. De exemplu, /bo*/ va găsi „buuuuuuuuuuuuuuuluuuuuuuuuuuuuulhului” în „A fantomă huiduită” și „b” în „A bird warbled”, dar nu va găsi nimic în „O capră a mormăit”.
+ Indică repetarea de 1 sau mai multe ori. Echivalent cu (1,). De exemplu, /a+/ se va potrivi cu „a” din „bomboane” și cu toate „a” din „caaaaaaandy”.
? Indică faptul că elementul poate fi prezent sau nu. De exemplu, /e?le?/ se va potrivi cu „el” în „înger” și „le” în „unghi”. , sau () , apoi specifică o căutare „non-lacomă” (repetând numărul minim posibil de ori, la cel mai apropiat element următor al modelului), spre deosebire de modul implicit „lacom”, în care numărul de repetări este maxim, chiar dacă elementul următor modelul este, de asemenea, potrivit. utilizat în previzualizare, care este descrisă în tabel de sub (?=) , (?!) și (?:) .
. (Punctul zecimal) reprezintă orice caracter, altul decât o linie nouă: \n \r \u2028 sau \u2029. (puteți folosi [\s\S] pentru a căuta orice caracter, inclusiv linii noi). De exemplu, /.n/ se va potrivi cu „an” și „on” în „nu, un măr este pe copac”, dar nu „nu”.
(x)Găsește x și își amintește. Aceasta se numește „paranteze de memorie”. De exemplu, /(foo)/ va găsi și își va aminti „foo” în „foo bar”. Subșirul găsit este stocat în matricea rezultatelor căutării sau în proprietățile predefinite ale obiectului RegExp: $1, ..., $9 În plus, parantezele combină ceea ce este conținut în ele într-un singur element de model. De exemplu, (abc)* - repetă abc 0 sau de mai multe ori.
(?:x)Găsește x, dar nu își amintește ce găsește. Aceasta se numește „paranteze de memorie”. Subșirul găsit nu este stocat în matricea de rezultate și în proprietățile RegExp Ca toate parantezele, ele combină ceea ce este în ele într-un singur submodel.
x(?=y)Găsește x numai dacă x este urmat de y. De exemplu, /Jack(?=Sprat)/ se va potrivi doar cu „Jack” dacă este urmat de „Sprat”. /Jack(?=Sprat|Frost)/ se va potrivi doar cu „Jack” dacă este urmat de „Sprat” sau „Frost”. Cu toate acestea, nici „Sprat” și nici „Frost” nu vor apărea în rezultatul căutării.
x(?!y)Găsește x numai dacă x nu este urmat de y. De exemplu, /\d+(?!\.)/ se va potrivi doar cu un număr dacă nu este urmat de un punct zecimal. /\d+(?!\.)/.exec("3.141") va găsi 141, dar nu 3.141.
x|yGăsește x sau y. De exemplu, /verde|roșu/ se va potrivi cu „verde” în „măr verde” și „roșu” în „măr roșu”.
(n)Unde n este un număr întreg pozitiv. Găsește exact n repetări ale elementului precedent. De exemplu, /a(2)/ nu va găsi „a” în „bomboane”, dar va găsi atât a în „caandy”, cât și primele două a în „caaandy”.
(n,)Unde n este un număr întreg pozitiv. Găsește n sau mai multe repetări ale unui element. De exemplu, /a(2,) nu va găsi „a” în „bomboane”, dar va găsi toate „a” în „caandy” și în „caaaaaaandy”.
(n,m)Unde n și m sunt numere întregi pozitive. Găsiți de la n la m repetări ale elementului.
Set de caractere. Găsește oricare dintre personajele enumerate. Puteți indica spațierea folosind o liniuță. De exemplu, - la fel ca . Se potrivește „b” în „piept” și „a” și „c” în „durere”.
[^xyz]Orice caracter altul decât cele specificate în set. De asemenea, puteți specifica un interval. De exemplu, [^abc] este același cu [^a-c] . Găsește „r” în „piept” și „h” în „chop”.
[\b]Găsește caracterul backspace. (A nu se confunda cu \b .)
\bGăsește o limită a unui cuvânt (latină), cum ar fi un spațiu. (A nu se confunda cu [\b]). De exemplu, /\bn\w/ se va potrivi cu „nu” în „noonday”; /\wy\b/ va găsi „ly” în „posibil ieri”.
\BNu indică o limită de cuvânt. De exemplu, /\w\Bn/ se va potrivi cu „on” în „noonday”, iar /y\B\w/ se va potrivi cu „ye” în „eventual ieri”.
\cXUnde X este o literă de la A la Z. Indică un caracter de control într-un șir. De exemplu, /\cM/ reprezintă caracterul Ctrl-M.
\dgăsește un număr din orice alfabet (al nostru este Unicode). Utilizați pentru a găsi numai numere obișnuite. De exemplu, /\d/ sau // se va potrivi cu „2” din „B2 este numărul suită”.
\DGăsește un caracter nenumeric (toate alfabetele). [^0-9] este echivalentul pentru numerele regulate. De exemplu, /\D/ sau /[^0-9]/ se va potrivi cu „B” din „B2 este numărul suitei”.
\sGăsește orice caracter de spațiu alb, inclusiv spațiu, tabulație, fluxuri de rând și alte caractere Unicode caractere cu spații albe. De exemplu, /\s\w*/ se va potrivi cu „bar” în „foo bar”.
\SGăsește orice caracter, cu excepția spațiului alb. De exemplu, /\S\w*/ se va potrivi cu „foo” în „foo bar”.
\vCaracter de filă verticală.
\wGăsește orice caracter de cuvânt (alfabet latin), inclusiv litere, cifre și caractere de subliniere. Echivalent. De exemplu, /\w/ se va potrivi cu „a” în „măr”, „5” în „5,28 USD” și „3” în „3D”.
\WGăsește orice caracter verbal non-(latin). Echivalent cu [^A-Za-z0-9_] . De exemplu, /\W/ și /[^$A-Za-z0-9_]/ se vor potrivi în mod egal cu „%” în „50%”.
Lucrul cu expresii regulate în Javascript

Lucrul cu expresii regulate în Javascript este implementat folosind metodele clasei String

exec(regexp) - găsește toate potrivirile (intrările din modelul obișnuit) într-un șir. Returnează o matrice (dacă există o potrivire) și actualizează proprietatea regexp, sau null dacă nu se găsește nimic. Cu modificatorul g - de fiecare dată când această funcție este apelată, va returna următoarea potrivire după cea anterioară găsită - aceasta este implementată prin menținerea unui index de offset al ultimei căutări.

match(regexp) - găsiți o parte dintr-un șir folosind un model. Dacă este specificat modificatorul g, atunci match() returnează o matrice cu toate potrivirile sau null (mai degrabă decât o matrice goală). Fără modificatorul g, această funcție funcționează ca exec();

test(regexp) - funcția verifică un șir pentru a se potrivi cu un model. Returnează adevărat dacă există o potrivire și false dacă nu există potrivire.

split(regexp) - Împarte șirul la care este apelat într-o matrice de subșiruri, folosind argumentul ca delimitator.

replace(regexp, mix) - metoda returnează un șir modificat în conformitate cu șablonul (expresie regulată). Primul parametru al expresiei regulate poate fi, de asemenea, un șir, mai degrabă decât o expresie regulată. Fără modificatorul g, metoda din linie înlocuiește doar prima apariție; cu modificatorul g - are loc o înlocuire globală, adică. toate aparițiile dintr-o linie dată sunt modificate.

mix - șablon de înlocuire, poate accepta valorile unui șir, șablon de înlocuire, funcție (numele funcției).

Caractere speciale în șirul de înlocuire Înlocuire prin funcție

Dacă specificați o funcție ca al doilea parametru, aceasta este executată la fiecare potrivire. O funcție poate genera și returna dinamic un șir de substituție. Primul parametru al funcției este subșirul găsit. Dacă primul argument de înlocuit este un obiect RegExp, atunci următorii n parametri conțin paranteze imbricate potriviri. Ultimii doi parametri sunt poziția în linia în care a avut loc potrivirea și linia în sine. Expresiile regulate sau expresiile regulate sunt intimidante pentru începători, dar esențiale pentru orice programator. Să înțelegem expresiile regulate din 5 exemple simple

cu JavaScript.

Dacă aveți o problemă și o veți rezolva cu expresii regulate, acum aveți două probleme. Există o vorbă. Expresiile obișnuite găsite în cod provoacă uneori frică și ură la oamenii care nu sunt familiarizați cu ele. Dar, de fapt, orice regex este doar o expresie șablon care poate rezolva problema într-o singură linie intreaga functie

. Cu toate acestea, pentru a construi o expresie obișnuită, trebuie să țineți cont de un set de reguli stricte în care un începător se poate confunda și poate face greșeli.

Caractere potrivite

Cele mai elementare expresii regulate sunt cele care se potrivesc cu un singur caracter. Iată regulile lor:

1. Un punct (.) se potrivește cu orice caracter. Dacă trebuie să căutați un anumit punct, trebuie să scăpați de el folosind caracterul „\” (\.).

var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit lest. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu."; // Atât „elit” cât și „elat” vor face. Punctul înseamnă că Orice va face simbol. var regex = /el.t/g; console.log(text.match(regex)); // „est” și „lest” vor funcționa la fel de bine. Semnul întrebării face „l” opțional. var regex2 = /l?est/g; console.log(text.match(regex2));

var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit lest. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu." ;

// Atât „elit” cât și „elat” vor face. Punctul înseamnă că orice simbol va funcționa.

var regex = /el.t/g ;

consolă. log(text. potrivire(regex));

// „est” și „lest” vor funcționa la fel de bine. Semnul întrebării face ca „l” să fie opțional.

var regex2 = /l?est/g ;

consolă. log(text. potrivire(regex2));

Potriviți mai multe personaje

Un set este unul sau mai multe caractere cuprinse între paranteze, de exemplu . O astfel de expresie va căuta numai acest set de caractere dintr-un șir - in în acest exemplu doar a, b sau c. Dimpotrivă, puteți căuta aparițiile oricărui simbol, cu excepția utilizării simbolului „^”. [^abc] se va potrivi cu orice caracter care nu este a, b sau c. De asemenea, puteți specifica o serie de caractere sau numere, de exemplu , .

Există seturi de caractere încorporate care facilitează scrierea expresiilor regulate. Ele sunt numite abrevieri sau stenografie. De exemplu, puteți scrie \D în schimb. Există abrevieri pentru alte caractere (inclusiv numere și caractere de subliniere) - \w și \W, precum și pentru spații - \s și \S.

// Numai „pisica” și „poate” vor funcționa, nu „mașină”. var text = „cu mașină pisică”; console.log(text.match(/ca/g)); // Totul va trece, cu excepția pisicii și a can (există un simbol ^) console.log(text.match(/ca[^tn]/g)); // Un alt exemplu în care doar numerele vor trece text = „Aș dori 8 cești de cafea, te rog.”; console.log("Câte cești: " + text.match(//g)); // Mod mai simplu folosind comanda rapidă \d console.log("Câte cupe: " + text.match(/\d/g)); // Trece totul, cu excepția numerelor console.log(text.match(/\D/g));

// Numai „pisica” și „poate” vor funcționa, nu „mașină”.

var text = "cu mașină cu pisică" ;

consolă. log(text. potrivire(/ca/g));

// Trece totul, în afară de pisică și poate (există un simbol ^)

consolă. jurnal (text . potrivire (/ca[^tn]/g ) ) ;

// Un alt exemplu în care vor trece numai numere

text = "Aș dori 8 căni de cafea, vă rog." ;

consolă. jurnal ("Câte cești: " + text . potrivi (//g ) ) ;

// Mod mai simplu folosind comanda rapidă \d

consolă. log("Câte cești: " + text . potriviți (/\d/g ) ) ;

// Trece totul, cu excepția numerelor

consolă. log(text. potrivire(/\D/g));

Cuvinte potrivite

În cele mai multe cazuri, trebuie să căutați mai degrabă cuvinte întregi decât personaje individuale. Acest lucru se face folosind modificatorii (+) și (-), care repetă un caracter sau un set de caractere.

Adăugarea (X) specifică numărul exact de repetări, (x, y) – intervalul (x și y sunt numere).

În plus, există un model special \b care se potrivește cu granițele de la sfârșitul cuvintelor.

var text = "Bună ziua, oamenii anului 1974. Vin din viitor. În 2014 avem pistoale laser, plăci hover și trăim pe lună!"; // Voi găsi ani. \d+ se va potrivi cu unul sau mai multe caractere var yearRegex = /\d+/g; console.log("Ani: ", text.match(yearRegex)); // Găsește toate propozițiile. Ofertele noastre încep cu majusculă, și se încheie cu un punct sau un semn de exclamare. var sentenceRegex = /.+?(\.|!)/g; console.log("Propoziții: ", text.match(sentenceRegex)); // Găsește toate cuvintele care încep cu „h”. Atât majuscule, cât și litere mici sunt potrivite pentru noi, așa că folosim modificatorul i // \b pentru a defini limita cuvântului. var hWords = /\bh\w+/ig; console.log("H Words: ", text.match(hWords)); // Găsește toate cuvintele de la 4 la 6 caractere var findWords = /\b\w(4,6)\b/g; console.log("Cuvinte între 4 și 6 caractere: ", text.match(findWords)); // Găsiți cuvinte mai lungi de 5 caractere console.log("Cuvinte de 5 caractere sau mai lungi: ", text.match(/\b\w(5,)\b/g)); // Găsește cuvinte cu exact 6 caractere lungi console.log("Cuvinte cu exact 6 caractere lungi: ", text.match(/\b\w(6)\b/g));

var text = "Bună ziua, oamenii anului 1974. Vin din viitor. În 2014 avem pistoale laser, plăci hover și trăim pe Lună!" ;

// Voi găsi ani. \d+ se potrivește cu unul sau mai multe caractere

var yearRegex = /\d+/g ;

consolă. log ("Anii: " , text . potrivire ( yearRegex ) ) ;

// Găsește toate propozițiile. Propozițiile noastre încep cu o literă mare și se termină cu un punct sau un semn de exclamare.

var sentenceRegex = /.+?(\.|!)/g ;

consolă. log("Propoziții: ", text. potrivire(sentenceRegex));

// Găsește toate cuvintele care încep cu „h”. Atât majuscule, cât și litere mici sunt potrivite pentru noi, așa că folosim modificatorul i

// \b pentru a determina limitele cuvintelor.

var hWords = /\bh\w+/i g ;

consolă. jurnal ("H Words: " , text . match ( hWords ) ) ;

// Găsește toate cuvintele de la 4 la 6 caractere

var findWords = /\b\w(4,6)\b/g ;

consolă. log("Cuvinte între 4 și 6 caractere: ", text. match(findWords));

// Găsiți cuvinte mai lungi de 5 caractere

consolă. jurnal ("Cuvinte de 5 caractere sau mai mult: " , text . potrivire (/\b\w(5,)\b/g ) ) ;

// Găsiți cuvinte cu exact 6 caractere lungime

consolă. jurnal ("Cuvinte de exact 6 caractere: " , text . potrivire (/\b\w(6)\b/g ) ) ;

Validarea întregului șir

În JavaScript, astfel de expresii pot fi folosite pentru a valida introducerea utilizatorului din câmpurile de text. Pentru validarea șirurilor de caractere se folosește o expresie regulată regulată, legată de începutul și sfârșitul unui fragment de text, folosind expresiile ^ (început de linie) și $ (sfârșit de linie) în acest scop. Aceste simboluri asigură că modelul pe care îl scrieți se întinde pe întreaga lungime a textului, mai degrabă decât să se potrivească doar cu o parte a acestuia.

În plus, în acest caz, folosim metoda test() a obiectului regex, care returnează adevărat sau fals atunci când testăm dacă expresia regulată se potrivește cu șirul.

// Avem o serie de șiruri de caractere, să găsim link-uri..com/", "123461", "https://site/?s=google", "http://nu este un URL valid", "abc http: / /invalid.url/" ]; var regex = /^https?:\/\/[\w\/?.&-=]+$/; var URL = ; for(var i = 0; i< strings.length; i++){ if(regex.test(strings[i])){ // Валидная ссылка urls.push(strings[i]); } } console.log("Valid URLs: ", urls);

// Avem o serie de șiruri, haideți să găsim link-urile.

var șiruri = [

„https://site/”,

„aceasta nu este o adresă URL”,

„https://google.com/”,

"123461" ,

„https://site/?s=google” ,

„http://nu este o adresă URL validă”,

„abc http://invalid.url/”

var regex = / ^ https ? : \ / \ / [ \ w \ / ? . & -= ] + $ / ;

var URL = ;

pentru (var i = 0; i< strings . length ; i ++ ) {

if (regex. test (șiruri [i])) (

URL-uri. împinge(șiruri[i]);

consolă. log("Adrese URL valide: ", URL);

Căutați și înlocuiți

Altul sarcină comună, care este facilitat de utilizarea expresiilor regulate, caută și înlocuiește text.

Sintaxa expresiilor regulate este destul de complexă și necesită un efort serios pentru a învăța. Cea mai bună îndrumare Cartea de astăzi despre expresia regulată este cartea lui J. Friedl „Expresii regulate”, care permite, potrivit autorului, „să înveți să gândești în expresii regulate”.

Concepte de bază

Expresia regulată este un mijloc de procesare a șirurilor de caractere sau a unei secvențe de caractere care definește un model de text.

Modificator - are scopul de a „instrui” expresia regulată.

Metacaracterele - caractere speciale, care servesc drept comenzi pentru limbajul expresiei regulate.

O expresie regulată este setată ca variabilă obișnuită, se folosește doar o bară oblică în loc de ghilimele, de exemplu: var reg=/reg_expression/

Prin cele mai simple șabloane înțelegem acele șabloane care nu necesită caractere speciale.

Să presupunem că sarcina noastră este să înlocuim toate literele „r” (mic și majuscule) cu latină majusculă„R” în frază Expresii regulate.

Creați un șablon var reg=/р/ și folosind metoda înlocui ne ducem la îndeplinire planurile



var reg=/р/

document.write(rezultat)

Ca rezultat, obținem linia - Expresii regulate, înlocuirea a avut loc numai la prima apariție a literei „p”, ținând cont de caz.

Dar acest rezultat nu se potrivește condițiilor sarcinii noastre... Aici avem nevoie de modificatorii „g” și „i”, care pot fi folosiți atât separat, cât și împreună. Acești modificatori sunt plasați la sfârșitul modelului de expresie regulată, după bară oblică și au următoarele semnificații:

modificatorul „g” - setează căutarea în linie ca „global”, adică. în cazul nostru, înlocuirea va avea loc pentru toate aparițiile literei „p”. Acum șablonul arată astfel: var reg=/р/g , înlocuindu-l în codul nostru


var str="Expresii regulate"
var reg=/р/g
var rezultat=str.replace(reg, "R")
document.write(rezultat)

obținem șirul - Expresii regulate.

modificatorul „i” - specifică o căutare fără diferențe de majuscule într-un șir Adăugând acest modificator la șablonul nostru var reg=/р/gi, după executarea scriptului vom obține rezultatul dorit al sarcinii noastre - expresii regulate.

Caractere speciale (metacaractere)

Metacaracterele specifică tipul de caractere ale șirului de căutare, modul în care șirul de căutare este înconjurat în text, precum și numărul de caractere tip separatîn textul care este vizualizat. Prin urmare, metacaracterele pot fi împărțite în trei grupuri:

  • Metacaractere pentru căutarea potrivirilor.
  • Metacaracterele cantitative.
  • Poziționarea metacaracterelor.
Metacaractere pentru potrivire

Sens

Descriere

limita de cuvinte

specifică o condiție în care modelul ar trebui să fie executat la începutul sau la sfârșitul unui cuvânt

/\ber/ se potrivește eroare, nu se potrivește erou sau cu player
/er/ se potrivește player, nu se potrivește erou sau cu eroare
/\ber\b/ nu se potrivește erou sau cu player sau cu eroare, poate coincide doar cu er

nu o limită de cuvinte

specifică o condiție în care modelul nu este executat la începutul sau la sfârșitul unui cuvânt

/\Ber/ se potrivește erou sau cu player, nu se potrivește eroare
/er\B/ se potrivește eroare sau cu player, nu se potrivește erou
/\Ber\B/ se potrivește erou, nu se potrivește player sau cu eroare

număr de la 0 la 9

/\d\d\d\d/ se potrivește cu orice număr din patru cifre

/\D\D\D\D/ nu se va potrivi 2005 sau 05.g sau №126 etc.

un singur caracter gol

se potrivește cu caracterul spațiu

\over\sbyte\ se potrivește numai peste octet

un singur caracter neblank

orice caracter, cu excepția spațiului

\over\Sbyte\ se potrivește peste octet sau cu peste_octeți, nu se potrivește peste octet sau peste octet

literă, număr sau liniuță

/A\w/ se potrivește A1 sau cu AB, nu se potrivește A+

nu o literă, un număr sau o liniuță de subliniere

/A\W/ nu se potrivește A1 sau cu AB, coincide cu A+

orice personaj

orice semne, litere, cifre etc.

/.../ se potrivește cu oricare trei caractere ABC sau !@4 sau 1 q

set de caractere

specifică o condiție în care modelul trebuie să fie executat pentru orice potrivire a caracterelor cuprinse între paranteze drepte

/WERTY/ meciuri QWERTY, Cu AWERTY

set de caractere neincluse

specifică o condiție în care modelul nu ar trebui să fie executat pentru nicio potrivire a caracterelor cuprinse între paranteze drepte

/[^QA]WERTY/ nu se potrivește QWERTY, Cu AWERTY

Caracterele afișate în tabelul „Metacaracterele de căutare potrivire” nu trebuie confundate cu secvența de caractere de evacuare utilizate în șiruri, cum ar fi \\t - tab, \\n - escape linie nouă etc.

Metacaracterele cantitative

Numărul de meciuri

Zero și Mai mult dată

/Ja*vaScript/ potrivește JavaScript sau cu JavaScript sau cu JavaScript, nu se potrivește JovaScript

Zero sau o dată

Numai /Ja?vaScript/ potriviri JavaScript sau cu JavaScript

Una sau mai multe ori

/Ja+vaScript/ potrivește JavaScript sau cu JavaScript sau cu JavaScript, nu se potrivește JavaScript

exact de n ori

Numai /Ja(2)vaScript/ se potrivește JavaScript

de n sau de mai multe ori

/Ja(2,)vaScript/ se potrivește JavaScript sau cu JavaScript, nu se potrivește JavaScript sau cu JavaScript

De cel puţin, de n ori, dar nu mai mult de m ori

Numai /Ja(2,3)vaScript/ se potrivește JavaScript sau cu JavaScript

Fiecare caracter listat în tabelul Metacaractere cantitative se aplică unui caracter sau metacaracter precedent din expresia regulată.

Poziționarea metacaracterelor

Ultimul set de metacaractere este menit să indice dacă se caută (dacă este important) subșirul la începutul liniei sau la sfârșit.

Câteva metode de lucru cu șabloane

inlocuieste - această metodă l-am folosit deja la începutul articolului, este conceput pentru a căuta un model și pentru a înlocui subșirul găsit cu un subșir nou.

exec - această metodă realizează o potrivire de șir cu modelul specificat de șablon. Dacă potrivirea modelului eșuează, se întoarce valoare nulă. ÎN altfel rezultatul este o matrice de subșiruri care se potrivesc cu modelul dat. /*Primul element al tabloului va fi egal cu șirul sursă care satisface modelul dat*/

De exemplu:


var reg=/(\d+).(\d+).(\d+)/
var arr=reg.exec(„M-am născut pe 15 septembrie 1980”)
document.write("Data nașterii: ", arr, "< br>")
document.write("Ziua de naștere: ", arr, "< br>")
document.write("Luna nașterii: ", arr, "< br>")
document.write("Anul nașterii: ", arr, "< br>")

Ca rezultat, obținem patru linii:
Data nasterii: 15.09.1980
Ziua de naștere: 15
Luna nasterii: 09
Anul nașterii: 1980

Concluzie

Articolul nu arată toate capacitățile și deliciile expresiilor regulate pentru un studiu mai profund al acestei probleme, vă sfătuiesc să studiați obiectul RegExp. De asemenea, vreau să vă atrag atenția asupra faptului că sintaxa expresiilor regulate nu este diferită atât în ​​JavaScript, cât și în PHP. De exemplu, pentru a verifica dacă un e-mail este introdus corect, expresia regulată atât pentru JavaScript, cât și pentru PHP va arăta la fel /+@+.(2,3)/i .

Unii oameni, când se confruntă cu o problemă, gândesc: „Oh, voi folosi expresii obișnuite”. Acum au două probleme.
Jamie Zawinski

Yuan-Ma a spus: „Este nevoie de multă forță pentru a tăia lemnul peste granulația lemnului. Este nevoie de mult cod pentru a programa în structura problemei.
Maestrul Yuan-Ma, „Cartea programării”

Instrumentele și tehnicile de programare supraviețuiesc și se răspândesc într-o manieră evolutivă haotică. Uneori nu cei frumoși și străluciți supraviețuiesc, ci pur și simplu cei care funcționează suficient de bine în domeniul lor - de exemplu, dacă sunt integrati într-o altă tehnologie de succes.

În acest capitol, vom discuta despre un astfel de instrument - expresiile regulate. Acesta este un mod de a descrie modele în date șir. Ei creează un limbaj mic, de sine stătător, care este inclus în JavaScript și în multe alte limbi și instrumente.

Programele regulate sunt atât foarte ciudate, cât și extrem de utile. Sintaxa lor este criptică, iar interfața lor de programare JavaScript este greoaie. Dar este un instrument puternic pentru explorarea și manipularea șirurilor. Odată ce le înțelegi, vei deveni un programator mai eficient.

Creați o expresie regulată Regular – tip de obiect. Poate fi creat apelând constructorul RegExp sau scriind șablonul dorit, înconjurat de bare oblice.

Var re1 = new RegExp("abc"); var re2 = /abc/;

Ambele expresii regulate reprezintă același model: caracterul „a” urmat de caracterul „b” urmat de caracterul „c”.

Dacă utilizați constructorul RegExp, atunci modelul este scris ca un șir obișnuit, astfel încât se aplică toate regulile privind barele oblice inverse.

A doua intrare, în care modelul este între bare oblice, tratează diferit barele oblice inverse. În primul rând, deoarece modelul se termină cu o oblică înainte, trebuie să punem o bară oblică inversă înaintea barei oblice pe care dorim să o includem în modelul nostru. În plus, barele oblice inverse care nu fac parte din caractere speciale precum \n vor fi păstrate (mai degrabă decât ignorate ca în șiruri de caractere) și vor schimba semnificația modelului. Unele caractere, cum ar fi semnul de întrebare sau plus, au o semnificație specială în expresiile obișnuite și, dacă trebuie să găsiți un astfel de caracter, acesta trebuie să fie precedat și de o bară oblică inversă.

Var eighteenPlus = /eighteen\+/;

Pentru a ști ce caractere trebuie să fie precedate de o bară oblică, trebuie să înveți o listă cu toate caracterele speciale din expresiile regulate. Acest lucru nu este încă posibil, așa că atunci când aveți îndoieli, puneți o bară oblică inversă în fața oricărui caracter care nu este o literă, un număr sau un spațiu.

Verificarea potrivirilor Motoarele obișnuite au mai multe metode. Cel mai simplu este testul. Dacă îi treceți un șir, acesta va returna o valoare booleană care indică dacă șirul conține o apariție a modelului dat.

Console.log(/abc/.test("abcde")); // → true console.log(/abc/.test("abxde")); // → fals

O secvență obișnuită constând numai din caractere nespeciale este pur și simplu o secvență a acestor caractere. Dacă abc este oriunde în linia pe care o testăm (nu doar la început), testul va returna true.

Căutarea unui set de caractere Puteți afla și dacă un șir conține abc folosind indexOf. Modelele obișnuite vă permit să mergeți mai departe și să creați modele mai complexe.

Să presupunem că trebuie să găsim orice număr. Când punem un set de caractere între paranteze drepte în expresia regulată, înseamnă că acea parte a expresiei se potrivește cu oricare dintre caracterele dintre paranteze.

Ambele expresii sunt în linii care conțin un număr.

Console.log(//.test(„în 1992”)); // → adevărat console.log(//.test(„în 1992”)); // → adevărat

Între paranteze drepte, o liniuță între două caractere este utilizată pentru a specifica un interval de caractere, în care secvența este specificată de codarea Unicode. Caracterele de la 0 la 9 sunt acolo doar pe rând (codurile de la 48 la 57), așa că le captează pe toate și se potrivește cu orice număr.

Mai multe grupuri de caractere au propriile lor abrevieri încorporate.

\d Orice număr
\w Caracter alfanumeric
\s caracter de spațiu alb (spațiu, tabulator, linie nouă etc.)
\D nu un număr
\W nu este un caracter alfanumeric
\S nu este un caracter alb
. orice caracter, cu excepția avansului de linie

Astfel, puteți seta formatul de dată și oră ca 30/01/2003 15:20 cu următoarea expresie:

Var dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/; console.log(dateTime.test("30-01-2003 15:20")); // → true console.log(dateTime.test("30-Jan-2003 15:20")); // → fals

Arată groaznic, nu-i așa? Există prea multe bare oblice inverse, ceea ce face modelul dificil de înțeles. Îl vom îmbunătăți puțin mai târziu.

Barele oblice inverse pot fi folosite și între paranteze drepte. De exemplu, [\d.] înseamnă orice număr sau punct. Observați că perioada din paranteze pătrate își pierde semnificația specială și devine pur și simplu o perioadă. Același lucru este valabil și pentru alte caractere speciale, cum ar fi +.

Puteți inversa un set de caractere - adică să spunem că trebuie să găsiți orice caracter, cu excepția celor care sunt în set - prin plasarea unui semn ^ imediat după paranteza pătrată de deschidere.

Var notBinary = /[^01]/; console.log(notBinary.test("1100100010100110")); // → false console.log(notBinary.test("1100100010200110")); // → adevărat

Repetarea părților modelului Știm cum să găsim un număr. Ce se întâmplă dacă trebuie să găsim întregul număr - o secvență de una sau mai multe cifre?

Dacă puneți semnul + după ceva în secvența obișnuită, aceasta va însemna că acest element poate fi repetat de mai multe ori. /\d+/ înseamnă una sau mai multe cifre.

Console.log(/"\d+"/.test(""123"")); // → adevărat console.log(/"\d+"/.test("""")); // → false console.log(/"\d*"/.test(""123"")); // → adevărat console.log(/"\d*"/.test("""")); // → adevărat

Asteriscul * are aproape aceeași semnificație, dar permite ca modelul să apară de zero ori. Dacă ceva este urmat de un asterisc, atunci nu împiedică niciodată modelul să fie în linie - apare doar acolo de zero ori.

Un semn de întrebare face ca o parte a modelului să fie opțională, ceea ce înseamnă că poate apărea zero sau o dată. În exemplul următor, poate apărea caracterul u, dar modelul se potrivește chiar și atunci când nu apare.

Var vecin = /neighbou?r/; console.log(vecin.test(„vecin”); // → adevărat console.log(vecin.test(„vecin”); // → adevărat

Acoladele sunt folosite pentru a specifica de câte ori trebuie să apară un model. (4) după un element înseamnă că trebuie să apară de 4 ori în linie. De asemenea, puteți specifica un interval: (2,4) înseamnă că elementul trebuie să apară de cel puțin 2 și nu mai mult de 4 ori.

O altă versiune a formatului de dată și oră, în care sunt permise zile, luni și ore de una sau două cifre. Și este, de asemenea, puțin mai lizibil.

Var dateTime = /\d(1,2)-\d(1,2)-\d(4) \d(1,2):\d(2)/; console.log(dateTime.test("30-1-2003 8:45")); // → adevărat

Puteți folosi spații deschise omițând unul dintre numere. (,5,) înseamnă că modelul poate apărea de la zero la cinci ori, iar (5,) înseamnă de la cinci sau mai multe.

Gruparea subexpresiilor Pentru a utiliza operatorii * sau + pe mai multe elemente simultan, puteți folosi paranteze. Partea expresiei regulate cuprinsă între paranteze este considerată un element din punctul de vedere al operatorilor.

Var cartoonCrying = /boo+(hoo+)+/i; console.log(cartoonCrying.test ("Boohoooohoohooo")); // → adevărat

Primul și al doilea plus se aplică numai celui de-al doilea O din boo și hoo. Al treilea + se referă la întregul grup (hoo+), găsind una sau mai multe astfel de secvențe.

Litera i de la sfârșitul expresiei face ca expresia regulată să nu țină seama de majuscule și minuscule - astfel încât B se potrivește cu b.

Potriviri și grupuri Metoda de testare este cea mai simplă metodă de verificare a expresiilor regulate. Vă spune doar dacă o potrivire a fost găsită sau nu. Obișnuiții au, de asemenea, o metodă exec, care va returna null dacă nu a fost găsit nimic și, în caz contrar, va returna un obiect cu informații despre potrivire.

Var potrivire = /\d+/.exec("unul doi 100"); console.log(potrivire); // → ["100"] console.log(match.index); // → 8

Obiectul returnat de exec are o proprietate index, care conține numărul caracterului de la care a avut loc potrivirea. În general, obiectul arată ca o matrice de șiruri, unde primul element este șirul care a fost verificat pentru o potrivire. În exemplul nostru, aceasta va fi succesiunea de numere pe care o căutam.

Șirurile au o metodă de potrivire care funcționează în același mod.

Console.log("unul doi 100".match(/\d+/)); // → ["100"]

Când o expresie obișnuită conține subexpresii grupate prin paranteze, textul care se potrivește cu aceste grupuri va apărea de asemenea în matrice. Primul element este întotdeauna o potrivire completă. A doua este partea care s-a potrivit cu primul grup (cel ale cărui paranteze au fost găsite mai întâi), apoi al doilea grup și așa mai departe.

Var quotedText = /"([^"]*)"/; console.log(quotedText.exec ("ea a spus "bună"")); // → [""bună ziua", "bună ziua"]

Când un grup nu este găsit deloc (de exemplu, dacă este urmat de un semn de întrebare), poziția sa în matrice este nedefinită. Dacă un grup se potrivește de mai multe ori, atunci numai ultimul meci va fi în matrice.

Console.log(/bad(ly)?/.exec(„rea”); // → [„prost”, nedefinit] console.log(/(\d)+/.exec(„123”)); // → ["123", "3"]

Grupurile sunt utile pentru a prelua părți de șiruri. Dacă nu vrem doar să verificăm dacă un șir are o dată, ci să îl extragem și să creăm un obiect reprezentând data, putem include secvențele de numere în paranteze și selectam data din rezultatul exec.

Dar mai întâi, o mică digresiune în care vom afla modul preferat de a stoca data și ora în JavaScript.

Tip de dată JavaScript are un tip de obiect standard pentru date – mai precis, momente în timp. Se numește Data. Dacă pur și simplu creați un obiect dată folosind new, veți obține data și ora curente.

Console.log(data noua()); // → Duminica 09 noiembrie 2014 00:07:57 GMT+0300 (CET)

De asemenea, puteți crea un obiect care conține un anumit timp

Console.log(new Date(2015, 9, 21)); // → Miercuri 21 octombrie 2015 00:00:00 GMT+0300 (CET) console.log(new Date(2009, 11, 9, 12, 59, 59, 999)); // → miercuri 09 decembrie 2009 12:59:59 GMT+0300 (CET)

JavaScript folosește o convenție în care numerele lunii încep cu zero și numerele zilei cu unu. Acest lucru este stupid și ridicol. Atenție.

Ultimele patru argumente (ore, minute, secunde și milisecunde) sunt opționale și sunt setate la zero dacă lipsesc.

Marcajele de timp sunt stocate ca număr de milisecunde care au trecut de la începutul anului 1970. Pentru vremurile înainte de 1970, sunt folosite numere negative (acest lucru se datorează convenției de timp Unix care a fost creată în acea perioadă). Metoda getTime a obiectului data returnează acest număr. Este în mod natural mare.
console.log(new Date(2013, 11, 19).getTime()); // → 1387407600000 console.log(new Date(1387407600000)); // → Joi, 19 decembrie 2013 00:00:00 GMT+0100 (CET)

Dacă dați constructorului Date un argument, acesta este tratat ca acest număr de milisecunde. Puteți obține valoarea curentă în milisecunde creând un obiect Date și apelând metoda getTime sau apelând funcția Date.now.

Obiectul Date are metode getFullYear, getMonth, getDate, getHours, getMinutes și getSeconds pentru a prelua componentele sale. Există, de asemenea, o metodă getYear care returnează un cod de două cifre destul de inutil, cum ar fi 93 sau 14.

Prin includerea părților relevante ale modelului în paranteze, putem crea un obiect dată direct dintr-un șir.

Funcția findDate(șir) ( var dateTime = /(\d(1,2))-(\d(1,2))-(\d(4))/; var potrivire = dateTime.exec(șir); return new Date(Număr(potrivire), Număr(potrivire) - 1, Număr(potrivire) ) console.log(findDate("30-1-2003")); // → Joi, 30 ianuarie 2003 00:00:00 GMT+0100 (CET)

Limitele cuvintelor și șirurilor Din păcate, findDate va extrage la fel de fericit data fără sens 00-1-3000 din șirul „100-1-30000”. Potrivirea poate avea loc oriunde în șir, deci în acest caz, pur și simplu va începe de la al doilea caracter și se va termina pe al doilea caracter.

Dacă trebuie să forțăm potrivirea să preia întregul șir, folosim etichetele ^ și $. ^ se potrivește cu începutul liniei, iar $ se potrivește cu sfârșitul. Prin urmare, /^\d+$/ se potrivește cu un șir care conține doar una sau mai multe cifre, /^!/ se potrivește cu un șir care începe cu un semn de exclamare și /x^/ nu se potrivește cu niciun șir (nu poate exista un x).

Dacă, pe de altă parte, vrem doar să ne asigurăm că data începe și se termină la granița unui cuvânt, folosim semnul \b. O limită a unui cuvânt poate fi începutul sau sfârșitul unei linii sau orice loc dintr-o linie unde există un caracter alfanumeric \w pe o parte și un caracter nealfanumeric pe cealaltă parte.

Console.log(/cat/.test(„concatenate”)); // → true console.log(/\bcat\b/.test(„concatenate”)); // → fals

Rețineți că eticheta de delimitare nu este un simbol. Este pur și simplu o constrângere care înseamnă că o potrivire are loc numai dacă este îndeplinită o anumită condiție.

Modele cu alegere Să presupunem că doriți să aflați dacă textul conține nu doar un număr, ci un număr urmat de porc, vaca sau pui la singular sau plural.

Ar fi posibil să scrieți trei expresii regulate și să le verificați una câte una, dar există o modalitate mai bună. Simbol | denotă o alegere între modelele din stânga și din dreapta acestuia. Și putem spune următoarele:

Var animalCount = /\b\d+ (porc|vacă|pui)s?\b/; console.log(animalCount.test("15 porci"); // → true console.log(animalCount.test("15 pui de porc")); // → fals

Parantezele delimitează porțiunea modelului la care se aplică | și mulți astfel de operatori pot fi plasați unul după altul pentru a indica o alegere dintre mai mult de două opțiuni.

Motor de căutare Expresiile regulate pot fi considerate diagrame de flux. Următoarea diagramă descrie un exemplu recent de animale.

O expresie se potrivește cu un șir dacă este posibil să găsiți o cale din partea stângă a diagramei la dreapta. Ne amintim poziția curentă în linie și de fiecare dată când trecem prin dreptunghi, verificăm dacă partea de linie imediat după poziția noastră în ea se potrivește cu conținutul dreptunghiului.

Aceasta înseamnă că verificarea dacă caracterul nostru obișnuit se potrivește cu șirul „cei 3 porci” atunci când parcurgeți diagrama de flux arată astfel:

La poziția 4 există o limită de cuvânt și trecem de primul dreptunghi
- incepand din pozitia a 4-a gasim numarul si trecem prin al doilea dreptunghi
- la poziția 5, o cale se închide înapoi în fața celui de-al doilea dreptunghi, iar a doua merge mai departe către dreptunghi cu un spațiu. Avem un spațiu, nu un număr și alegem a doua cale.
- acum suntem pe pozitia 6, inceputul “porcilor”, si la tripla ramificare a potecilor. Nu există „vacă” sau „pui” în linie, dar există „porc”, așa că alegem această cale.
- în poziția 9 după bifurcația triplă, o cale ocolește „s” și merge la ultimul dreptunghi cu o limită de cuvânt, iar a doua trece prin „s”. Avem un „s”, așa că mergem acolo.
- la poziția 10 suntem la sfârșitul liniei și doar limita cuvântului se poate potrivi. Capătul liniei este considerat graniță și trecem prin ultimul dreptunghi. Și acum am găsit cu succes șablonul nostru.

Practic, modul în care funcționează expresiile regulate este că algoritmul începe la începutul șirului și încearcă să găsească o potrivire acolo. În cazul nostru, există o limită a cuvântului, deci trece de primul dreptunghi - dar nu există niciun număr acolo, așa că se împiedică de al doilea dreptunghi. Apoi trece la al doilea caracter din șir și încearcă să găsească o potrivire acolo... Și așa mai departe până când găsește o potrivire sau ajunge la sfârșitul șirului, caz în care nu se găsește nicio potrivire.

Rollbacks Regular /\b(+b|\d+|[\da-f]h)\b/ se potrivește fie cu un număr binar urmat de un b, cu un număr zecimal fără sufix, fie cu un număr hexazecimal (numerele de la 0 la 9 sau caracterele de la a la h), urmate de h. Diagrama relevanta:

Când căutați o potrivire, se poate întâmpla ca algoritmul să ia calea de sus (număr binar), chiar dacă nu există un astfel de număr în șir. Dacă există o linie „103”, de exemplu, este clar că numai după ce ajunge la numărul 3 algoritmul va înțelege că este pe calea greșită. În general, linia se potrivește cu secvența obișnuită, doar că nu în acest fir.

Apoi algoritmul revine. La o bifurcație, își amintește poziția curentă (în cazul nostru, acesta este începutul liniei, imediat după limita cuvântului), astfel încât să puteți întoarce înapoi și să încercați o altă cale dacă cea aleasă nu funcționează. Pentru șirul „103”, după ce ați întâlnit un trei, se va întoarce și va încerca să treacă prin calea zecimală. Acest lucru va funcționa, astfel încât o potrivire va fi găsită.

Algoritmul se oprește imediat ce găsește o potrivire completă. Aceasta înseamnă că, chiar dacă mai multe opțiuni pot fi potrivite, se folosește doar una dintre ele (în ordinea în care apar în secvența obișnuită).

Backtracking apare atunci când se utilizează operatori de repetiție precum + și *. Dacă căutați /^.*x/ în șirul „abcxe”, partea regex.* va încerca să consume întregul șir. Algoritmul va realiza apoi că are nevoie și de „x”. Deoarece nu există niciun „x” după sfârșitul șirului, algoritmul va încerca să caute o potrivire deplasând înapoi cu un caracter. După abcx nu există nici un x, apoi se întoarce din nou, de data aceasta la subșirul abc. Iar după linie, găsește x și raportează o potrivire reușită, în pozițiile de la 0 la 4.

Puteți scrie o rutină obișnuită care va duce la mai multe derulări. Această problemă apare atunci când modelul se poate potrivi cu intrarea în multe moduri diferite. De exemplu, dacă facem o greșeală când scriem expresia regulată pentru numere binare, s-ar putea să scriem accidental ceva de genul /(+)+b/.

Dacă algoritmul ar căuta un astfel de model într-un șir lung de 0 și 1 care nu avea un „b” la sfârșit, ar trece mai întâi prin bucla interioară până când rămâne fără cifre. Apoi va observa că nu există „b” la sfârșit, va întoarce o poziție înapoi, va trece prin bucla exterioară, va renunța din nou, va încerca să se întoarcă înapoi în altă poziție de-a lungul buclei interioare... Și va continua pentru a căuta în acest fel, folosind ambele bucle. Adică, cantitatea de lucru cu fiecare caracter al liniei se va dubla. Chiar și pentru câteva zeci de personaje, găsirea unei potriviri va dura foarte mult timp.

Metoda de înlocuire Șirurile au o metodă de înlocuire care poate înlocui o parte dintr-un șir cu un alt șir.

Console.log("tata".replace("p", "m")); // → hartă

Primul argument poate fi și o expresie regulată, caz în care prima apariție a expresiei regulate din linie este înlocuită. Când opțiunea „g” (globală) este adăugată la expresia regulată, toate aparițiile sunt înlocuite, nu doar prima

Console.log("Borobudur".replace(//, "a")); // → Barobudur console.log("Borobudur".replace(//g, "a")); // → Barabadar

Ar fi logic să treceți opțiunea „înlocuiți tot” printr-un argument separat sau printr-o metodă separată, cum ar fi înlocuiți toate. Dar, din păcate, opțiunea este transmisă prin sistemul obișnuit în sine.

Puterea deplină a expresiilor regulate este dezvăluită atunci când folosim link-uri către grupuri găsite într-un șir, specificate în expresia regulată. De exemplu, avem o linie care conține numele persoanelor, câte un nume pe rând, în formatul „Nume, Prenume”. Dacă trebuie să le schimbăm și să eliminăm virgula pentru a obține „Nume de familie”, scriem următoarele:

Console.log(„Hopper, Grace\nMcCarthy, John\nRitchie, Dennis” .replace(/([\w ]+), ([\w ]+)/g, „$2 $1”); // → Grace Hopper // John McCarthy // Dennis Ritchie

$1 și $2 în linia de înlocuire se referă la grupuri de caractere cuprinse între paranteze. $1 este înlocuit cu textul care se potrivește cu primul grup, $2 cu al doilea grup și așa mai departe, până la $9. Întreaga potrivire este conținută în variabila $&.

De asemenea, puteți trece o funcție ca al doilea argument. Pentru fiecare înlocuire, va fi apelată o funcție ale cărei argumente vor fi grupurile găsite (și toată partea corespunzătoare a liniei), iar rezultatul acesteia va fi inserat într-o nouă linie.

Exemplu simplu:

Var s = „cia și fbi”; console.log(s.replace(/\b(fbi|cia)\b/g, function(str) ( return str.toUpperCase(); ))); // → CIA și FBI

Iată una mai interesantă:

Stock de var = „1 lămâie, 2 varză și 101 ouă”; funcția minusOne(potrivire, cantitate, unitate) ( cantitate = Număr (cantitate) - 1; dacă (cantitate == 1) // a rămas doar unul, eliminați „s” de la sfârșit unit = unit.slice(0, unit. lungime - 1; else if (cantitate == 0) suma = "nu" + unitate) console.log(stock.replace(/(\d+)/g, minusOne); ); // → fără lămâie, 1 varză și 100 de ouă

Codul ia un șir, găsește toate aparițiile numerelor urmate de un cuvânt și returnează un șir cu fiecare număr redus cu unul.

Grupul (\d+) intră în argumentul cantitate, iar (\w+) intră în argumentul unitate. Funcția convertește suma într-un număr - și aceasta funcționează întotdeauna, deoarece modelul nostru este \d+. Și apoi face modificări cuvântului, în cazul în care rămâne doar 1 articol.

Lăcomia Este ușor de folosit înlocuire pentru a scrie o funcție care elimină toate comentariile din codul JavaScript. Iată prima încercare:

Funcția stripComments(cod) ( return code.replace(/\/\/.*|\/\*[^]*\*\//g, ""); ) console.log(stripComments("1 + /* 2 */3")); // → 1 + 3 console.log(stripComments("x = 10;// zece!")); // → x = 10; console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 1

Partea dinaintea operatorului „sau” se potrivește cu două bare oblice urmate de orice număr de caractere, cu excepția liniilor noi. Partea care elimină comentariile pe mai multe rânduri este mai complexă. Folosim [^], i.e. orice caracter care nu este gol ca o modalitate de a găsi orice personaj. Nu putem folosi un punct, deoarece comentariile de bloc continuă pe o linie nouă, iar caracterul de linie nouă nu se potrivește cu punctul.

Dar rezultatul exemplului anterior este incorect. De ce?

Partea [^]* va încerca mai întâi să capteze cât mai multe personaje. Dacă din această cauză următoarea parte a secvenței obișnuite nu găsește o potrivire, va derula un caracter înapoi și va încerca din nou. În exemplu, algoritmul încearcă să prindă întreaga linie, apoi se derulează înapoi. După ce a derulat înapoi 4 caractere, el va găsi */ în linie - și nu este ceea ce ne-am dorit. Am vrut să luăm un singur comentariu, și nu să mergem la sfârșitul rândului și să găsim ultimul comentariu.

Din această cauză, spunem că operatorii de repetiție (+, *, ? și ()) sunt lacomi, adică mai întâi apucă cât pot și apoi se întorc. Dacă puneți o întrebare după un astfel de operator (+?, *?, ??, ()?), ei se vor transforma în non-lacomi și vor începe să găsească cele mai mici apariții posibile.

Și de asta avem nevoie. Forțând asteriscul să găsească potriviri în numărul minim posibil de caractere dintr-o linie, consumăm doar un bloc de comentarii și nimic mai mult.

Funcția stripComments(cod) ( return code.replace(/\/\/.*|\/\*[^]*?\*\//g, ""); ) console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 + 1

Multe erori apar atunci când se folosesc operatori lacomi în loc de cei nelacomi. Când utilizați operatorul de repetare, luați în considerare întotdeauna mai întâi operatorul non-lacom.

Crearea dinamică a obiectelor RegExp În unele cazuri, modelul exact nu este cunoscut în momentul în care este scris codul. De exemplu, va trebui să căutați numele utilizatorului în text și să îl includeți în liniuțe de subliniere. Deoarece veți ști numele numai după rularea programului, nu puteți utiliza notația oblică.

Dar puteți construi șirul și utilizați constructorul RegExp. Iată un exemplu:

Var nume = „harry”; var text = „Și Harry are o cicatrice pe frunte.”; var regexp = new RegExp("\\b(" + nume + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Și _Harry_ are o cicatrice pe frunte.

Când creăm limite de cuvinte, trebuie să folosim bare oblice duble, deoarece le scriem într-o linie normală, și nu într-o secvență obișnuită cu bare oblice înainte. Al doilea argument la RegExp conține opțiuni pentru expresii regulate - în cazul nostru „gi”, adică. globală și insensibilă la majuscule și minuscule.

Dar dacă numele este „dea+hlrd” (dacă utilizatorul nostru este un kulhatzker)? Ca rezultat, vom obține o expresie regulată fără sens care nu va găsi potriviri în șir.

Putem adăuga bare oblice inverse înaintea oricărui personaj care nu ne place. Nu putem adăuga bare oblice inverse înainte de litere deoarece \b sau \n sunt caractere speciale. Dar puteți adăuga bare oblice înaintea oricăror caractere non-alfanumerice fără probleme.

Var name = "dea+hlrd"; var text = "Acest dea+hlrd enervează pe toată lumea."; var escape = name.replace(/[^\w\s]/g, "\\$&"); var regexp = new RegExp("\\b(" + escape + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Această _dea+hlrd_ a enervat pe toată lumea.

Metoda de căutare Metoda indexOf nu poate fi utilizată cu expresii regulate. Dar există o metodă de căutare, care se așteaptă doar la expresia regulată. La fel ca indexOf, returnează indexul primei apariții sau -1 dacă nu apare niciuna.

Console.log("cuvânt".search(/\S/)); // → 2 console.log(" ".search(/\S/)); // → -1

Din păcate, nu există nicio modalitate de a spune metodei să caute o potrivire începând cu un anumit offset (cum poți face cu indexOf). Asta ar fi de ajutor.

Proprietatea lastIndex De asemenea, metoda exec nu oferă o modalitate convenabilă de a începe o căutare dintr-o poziție dată din șir. Dar oferă un mod incomod.

Un obiect regex are proprietăți. Una dintre ele este sursa, care conține un șir. Un altul este lastIndex, care controlează, în anumite condiții, unde va începe următoarea căutare a aparițiilor.

Aceste condiții includ faptul că opțiunea globală g trebuie să fie prezentă și că căutarea trebuie făcută folosind metoda exec. O soluție mai rezonabilă ar fi să permiteți pur și simplu să se transmită un argument suplimentar către exec, dar caracterul rezonabil nu este o caracteristică fundamentală a interfeței JavaScript regex.

Var model = /y/g; pattern.lastIndex = 3; var potrivire = pattern.exec("xyzzy"); console.log(match.index); // → 4 console.log(pattern.lastIndex); // → 5

Dacă căutarea a avut succes, apelul exec actualizează proprietatea lastIndex pentru a indica poziția după apariția găsită. Dacă nu a avut succes, lastIndex este setat la zero - la fel ca lastIndex al obiectului nou creat.

Atunci când utilizați o variabilă obișnuită globală și apeluri multiple de exec, aceste actualizări automate lastIndex pot cauza probleme. Serverul dvs. obișnuit poate începe să caute din poziția rămasă de la apelul anterior.

Var digit = /\d/g; console.log(digit.exec ("aici este: 1")); // → ["1"] console.log(digit.exec("și acum: 1")); // → nul

Un alt efect interesant al opțiunii g este că schimbă modul în care funcționează metoda de potrivire. Când este apelat cu această opțiune, în loc să returneze o matrice similară cu rezultatul exec, găsește toate aparițiile modelului din șir și returnează o matrice a subșirurilor găsite.

Console.log("Banana".match(/an/g)); // → ["un", "un"]

Așa că aveți grijă cu variabilele globale regulate. Cazurile în care sunt necesare - înlocuiți apelurile sau locurile în care utilizați în mod specific lastIndex - sunt probabil toate cazurile în care ar trebui să fie utilizate.

Cicluri de apariție

O sarcină tipică este să iterați prin toate aparițiile unui model dintr-un șir, astfel încât să poată accesa obiectul potrivire din corpul buclei, folosind lastIndex și exec.

Var input = "O linie cu 3 numere în ea... 42 și 88."; număr var = /\b(\d+)\b/g; var potrivire; while (potrivire = număr.exec(intrare)) console.log(„Găsit”, potrivire, „pe”, potrivire.index); // → Găsit 3 la 14 // Găsit 42 la 33 // Găsit 88 la 40

Se profită de faptul că valoarea atribuirii este valoarea atribuită. Folosind match = re.exec(input) ca o condiție într-o buclă while, căutăm la începutul fiecărei iterații, stocăm rezultatul într-o variabilă și încheiem bucla când sunt găsite toate potrivirile.

Analizarea fișierelor INI

Pentru a încheia capitolul, să ne uităm la o problemă folosind expresii regulate. Imaginați-vă că scriem un program care colectează automat informații despre inamicii noștri prin Internet. (Nu vom scrie întregul program, ci doar partea care citește fișierul de setări. Ne pare rău.) Fișierul arată astfel:

Searchengine=http://www.google.com/search?q=$1 spitefulness=9.7 ; se pune punct și virgulă înaintea comentariilor; fiecare secțiune se referă la un inamic diferit nume complet=Larry Doe tip=website taur grădiniță=http://www.geocities.com/CapeCanaveral/11451 fullname=Gargamel tip=vrăjitor rău outputdir=/home/marijn/enemies/gargamel

Formatul exact de fișier (care este destul de utilizat pe scară largă și se numește de obicei INI) este următorul:

Liniile goale și liniile care încep cu punct și virgulă sunt ignorate
- liniile cuprinse între paranteze drepte încep o nouă secțiune
- linii care conțin un identificator alfanumeric urmat de = adăugați o setare în această secțiune

Toate celelalte sunt date incorecte.

Sarcina noastră este să convertim un astfel de șir într-o matrice de obiecte, fiecare cu o proprietate de nume și o matrice de setări. Este necesar un obiect pentru fiecare secțiune, iar altul este necesar pentru setările globale din partea de sus a fișierului.

Deoarece fișierul trebuie analizat linie cu linie, este o idee bună să începeți prin a împărți fișierul în linii. Pentru a face acest lucru, am folosit string.split("\n") în Capitolul 6. Unele sisteme de operare folosesc nu un caracter \n pentru întreruperi de linie, ci două - \r\n. Deoarece metoda split ia ca argument expresiile regulate, putem împărți linii folosind expresia /\r?\n/, permițând atât \n cât și \r\n între linii.

Funcția parseINI(șir) ( // Să începem cu un obiect care conține setări de nivel superior var currentSection = (nume: nul, câmpuri: ); var categorii = ; string.split(/\r?\n/).forEach(funcție (line ) ( var potrivire; if (/^\s*(;.*)?$/.test(line)) ( return; ) else if (match = line.match(/^\[(.*)\) ]$ /)) ( currentSection = (nume: potrivire, câmpuri: ); categories.push(currentSection); ) else if (potrivire = line.match(/^(\w+)=(.*)$/)) ( currentSection. fields.push((nume: potrivire, valoare: potrivire) else ( throw new Error("Linia "" + linia + "" conține date invalide."); ));

Codul parcurge toate liniile, actualizând obiectul secțiunii curente „secțiunea curentă”. În primul rând, verifică dacă linia poate fi ignorată folosind expresia regulată /^\s*(;.*)?$/. Vă puteți imagina cum funcționează asta? Partea dintre paranteze se potrivește cu comentariile, nu? face astfel încât caracterul obișnuit să se potrivească, de asemenea, linii formate doar din spații.

Dacă linia nu este un comentariu, codul verifică dacă începe o nouă secțiune. Dacă da, creează un nou obiect pentru secțiunea curentă, la care se adaugă setările ulterioare.

Ultima posibilitate semnificativă este ca șirul să fie o setare normală, caz în care este adăugat obiectului curent.

Dacă niciuna dintre opțiuni nu funcționează, funcția afișează o eroare.

Observați cum utilizarea frecventă a ^ și $ asigură că expresia se potrivește întregului șir, mai degrabă decât doar o parte a acestuia. Dacă nu le utilizați, codul va funcționa în general, dar uneori va produce rezultate ciudate și eroarea va fi dificil de găsit.

Construcția if (match = string.match(...)) este similară cu trucul de a folosi atribuirea ca condiție într-o buclă while. Adesea nu știi că apelul de potrivire va reuși, așa că poți accesa doar obiectul rezultat în interiorul unui bloc if care îl verifică. Pentru a nu rupe lanțul frumos al verificărilor if, atribuim rezultatul căutării unei variabile și folosim imediat această atribuire ca verificare.

Caractere internaționale Datorită implementării inițial simple a limbajului și fixării ulterioare a unei astfel de implementări „în granit”, expresiile regulate JavaScript sunt stupide cu caractere care nu se găsesc în limba engleză. De exemplu, caracterul „litera”, din punctul de vedere al expresiilor regulate JavaScript, poate fi una dintre cele 26 de litere ale alfabetului englez și, din anumite motive, și un caracter de subliniere. Litere precum é sau β, care sunt în mod clar litere, nu se potrivesc cu \w (și se vor potrivi cu \W, care este o non-litera).

Într-o întorsătură ciudată, istoricul \s (spațiu) se potrivește cu toate caracterele care sunt considerate spații albe în Unicode, inclusiv lucruri precum spațiul neîntrerupt sau separatorul de vocale mongole.

Unele implementări regex în alte limbi au sintaxă specială pentru căutarea categoriilor speciale de caractere Unicode, cum ar fi „toate majuscule”, „toate semnele de punctuație” sau „caracterele de control”. Există planuri de a adăuga astfel de categorii la JavaScript, dar ele, aparent, nu vor fi implementate în curând.

Concluzie

Regularii sunt obiecte care reprezintă modele de căutare în șiruri. Ei folosesc propria sintaxă pentru a exprima aceste modele.

/abc/ Secvență de caractere
// Orice caracter din listă
/[^abc]/ Orice caracter, cu excepția caracterelor din listă
// Orice caracter din interval
/x+/ Una sau mai multe apariții ale modelului x
/x+?/ Una sau mai multe apariții, nelacom
/x*/ Zero sau mai multe apariții
/x?/ Zero sau o apariție
/x(2,4)/ De la două până la patru apariții
/(abc)/ Grup
/a|b|c/ Oricare dintre mai multe modele
/\d/ Orice număr
/\w/ Orice caracter alfanumeric („litera”)
/\s/ Orice caracter alb
/./ Orice caracter, cu excepția liniilor noi
/\b/ Limita cuvântului
/^/ Începutul liniei
/$/ Sfârșitul rândului

Regex are o metodă de testare pentru a verifica dacă modelul este în șir. Există o metodă exec care returnează o matrice care conține toate grupurile găsite. Matricea are o proprietate index, care conține numărul caracterului de la care a avut loc potrivirea.

Șirurile au o metodă de potrivire pentru a potrivi modelele și o metodă de căutare care returnează doar poziția de pornire a apariției. Metoda de înlocuire poate înlocui aparițiile unui model cu un alt șir. În plus, puteți trece o funcție de înlocuit care va construi o linie de înlocuire pe baza șablonului și a grupurilor găsite.

Caracterele obișnuite au setări care sunt scrise după bara oblică de închidere. Opțiunea i face ca expresia regulată să nu țină seama de majuscule și minuscule, iar opțiunea g o face globală, ceea ce, printre altele, face ca metoda de înlocuire să înlocuiască toate aparițiile găsite, nu doar prima.

Constructorul RegExp poate fi folosit pentru a crea expresii regulate din șiruri.

Regulatoarele sunt un instrument ascuțit cu un mâner inconfortabil. Ele simplifică foarte mult unele sarcini și pot deveni de negestionat atunci când rezolvăm alte probleme complexe. O parte a învățării să folosești regex este să poți rezista tentației de a-l umple cu o sarcină pentru care nu este destinat.

Exerciții Inevitabil, atunci când rezolvi probleme, vei întâlni cazuri de neînțeles, iar uneori s-ar putea să disperi când vezi comportamentul imprevizibil al unor expresii regulate. Uneori ajută să studiezi comportamentul unui joc obișnuit printr-un serviciu online precum debuggex.com, unde poți vedea vizualizarea acestuia și îl poți compara cu efectul dorit. Golful obișnuit „Golf” în cod este un joc în care trebuie să exprimi un programul dat într-un număr minim de caractere. Golful obișnuit este un exercițiu practic de a scrie cei mai mici obișnuiți posibil pentru a găsi un model dat și doar atât.

Pentru fiecare dintre sublinii, scrieți o expresie regulată pentru a verifica locația lor în linie. Motorul obișnuit ar trebui să găsească numai aceste subșiruri specificate. Nu vă faceți griji cu privire la limitele cuvintelor decât dacă sunt menționate în mod specific. Când aveți un model obișnuit de lucru, încercați să îl reduceți.

Mașină și pisică
- pop și prop
- dihor, feribot și ferrari
- Orice cuvânt care se termină în ious
- Un spațiu urmat de un punct, virgulă, două puncte sau punct și virgulă.
- Un cuvânt mai lung de șase litere
- Cuvânt fără litere e

// Introduceți expresiile regulate verify(/.../, ["mașina mea", "pisicile rele"], ["camper", "high art"]); verifică(/.../, ["cultură pop", "recuzită nebună"], ["plop"]); verifica(/.../, ["dihor", "feribot", "ferrari"], ["ferrum", "transfer A"]); verifica(/.../, [„cât de delicios”, „cameră spațioasă”], [„ruinator”, „conștiință”]); verifică(/.../, ["punctuație proastă."], ["escape the dot"]); verifică(/.../, ["hottenottententen"], ["nu", "hotten totten tenten"]); verifică(/.../, [„ornitorinc roșu”, „cuib clătinat”], [„pat de pământ”, „maimuță care învață”]); function verify(regexp, yes, no) ( // Ignora exercitiile neterminate daca (regexp.source == "...") return; yes.forEach(function(s) ( if (!regexp.test(s))) consola .log("Nu a fost găsită "" + s + """ )); ); ));

Citate în text Să presupunem că ați scris o poveste și ați folosit ghilimele simple pentru a indica dialogul. Acum doriți să înlocuiți ghilimelele de dialog cu ghilimele duble și să lăsați ghilimele simple în abrevieri ale cuvintelor precum aren’t.

Veniți cu un model care să facă distincția între aceste două utilizări ale ghilimelelor și scrieți un apel la metoda înlocuire care face înlocuirea.

Din nou numere Secvențele de numere pot fi găsite cu o expresie regulată simplă /\d+/.

Scrieți o expresie care găsește numai numere scrise în stil JavaScript. Trebuie să suporte un posibil minus sau plus înaintea numărului, un punct zecimal și notația științifică 5e-3 sau 1E10 - din nou cu un posibil plus sau minus. De asemenea, rețineți că este posibil să nu existe neapărat numere înainte sau după punct, dar numărul nu poate consta dintr-un singur punct. Adică, .5 sau 5. sunt numere valide, dar un punct în sine nu este.

// Introduceți secvența obișnuită aici. var număr = /^...$/; // Teste: ["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"] .forEach(funcție(i) ( dacă (!număr.test(e)) console.log("Nu am găsit "" + s + """); )); ["1a", "+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."].forEach(funcție(i) ( if (număr.test(e)) console.log("Acceptat incorect "" + s + """); ));

  • Serghei Savenkov

    un fel de recenzie „scurtă”... de parcă s-ar grăbi undeva