Expresii regulate orice număr. Sintaxa expresiei regulate

Iată câteva exemple de expresii regulate.

    karova - evident un șablon în care se încadrează cuvântul karova;

    \b(shift|unshift|pop|push|splice)\b - oricare dintre cuvintele enumerate;

    ^\s+ - unul sau mai multe spații sau file la începutul unei linii.

În expresiile regulate, caracterele alfanumerice se reprezintă de obicei. De exemplu, modelul Hello specifică căutarea caracterului H urmat de e , apoi l , etc.

Dacă un simbol este dificil sau incomod de specificat literal, puteți folosi literale deja cunoscute de noi: \n , \t și altele. Aceasta înseamnă că caracterul \ inclus în expresia regulată nu se mai poate autodesemna, deoarece schimbă semnificația caracterului care îl urmează: în special, litera n, împreună cu caracterul backslash precedent, denotă caracterul de sfârșit de linie. Dacă doriți să includeți caracterul \ însuși în model, ar trebui să utilizați literalul \\ .

Există și alte simboluri cărora li se dă o semnificație specială în modele în loc să se reprezinte. Astfel de simboluri sunt numite metacaracterele. Să dăm câteva exemple de metacaractere, fără a indica încă semnificația lor specială (lista nu este exhaustivă): \.-()()?*+^$| .

Unele personaje nu se dovedesc întotdeauna a fi metacaractere, ci doar atunci când se încadrează într-un anumit context. Unele metacaractere au semnificații diferite în funcție de context.

Dacă trebuie să inserați un metacaracter într-o expresie obișnuită, făcându-l să nu mai aibă sens, ar trebui să îl protejați ( scut), plasând o bară oblică inversă în fața lui. De exemplu, un semn plus într-o expresie regulată este inserat ca \+ .

Modelul desemnează unul dintre caracterele enumerate între paranteze drepte. Dacă, de exemplu, ne interesează cuvântul Bună ziua, nu contează dacă este scris cu majuscule sau mic, modelul va fi astfel: ello. Iată un model care reprezintă o literă vocală mică în alfabetul englez: . Un alt exemplu este o clasă de caractere formată din ambele paranteze drepte: [\[\]] .

Dacă o clasă de caractere include caractere care sunt consecutive în tabelul de coduri, este suficient să indicați primul și ultimul caracter, inserând o cratimă între ele. De exemplu, o clasă care reprezintă orice cifră zecimală poate fi specificată ca . O literă din alfabetul englez este notă cu (aici ne bazăm pe faptul că în orice tabel de coduri majuscule și mici litere engleze intra in blocuri continue in ordine alfabetică; cu toate acestea, un bloc de litere mici nu urmează imediat un bloc de litere mari).

Este posibil să se definească o clasă de caractere formată din toate caracterele, cu excepția celor enumerate - așa-numitele negarea clasei de caractere. Pentru a face acest lucru, un semn circumflex ^ este inserat imediat după paranteza pătrată de deschidere înainte de enumerare. Orice caracter care nu este un număr poate fi reprezentat ca [^0-9] .

Există notații speciale pentru unele clase de caractere populare:

Când un șir este potrivit cu o expresie regulată, fiecare caracter sau clasă de caractere din șablon este potrivit cu un caracter din șir. Există însă construcții care nu indică prezența unui anumit personaj, ci un anumit loc (gol) în linie. Astfel de construcții se numesc legături, sau ancore

Cele mai frecvent utilizate ancore sunt ancora (^) și capătul ($) al șirului. Ancora de început a liniei ar trebui să fie plasată la începutul modelului, iar ancora de capăt ar trebui să fie plasată la sfârșit.

De exemplu, cuvintele rusești precum antidot, antisemitism sau antiparticulă se potrivesc tiparului ^anti. Fără o legătură, liniile care nu încep cu „anti-”, dar care conțin această combinație de litere în interior, ar fi de asemenea potrivite, de exemplu, mercantilism. Pentru a căuta cuvinte care se termină în „-tsya” aveți nevoie de modelul tsya$ (sîntem aproape 100% siguri că toate astfel de cuvinte sunt verbe reflexive la infinitiv). Nimic nu vă împiedică să utilizați ambele legături în șablon.

O altă ancoră utilă este cuvântul boundary anchor \b . Se potrivește spațiul dintr-un șir dintre caractere, dintre care unul este din clasa \w și celălalt din clasa \W (în orice ordine). Această ancoră poate potrivi și începutul sau sfârșitul unui șir (în acest caz, șirul este considerat a fi înconjurat de caractere imaginare din clasa \W).

Dacă căutăm un fragment care ar trebui să se potrivească cu unul dintre mai multe șabloane, trebuie să listăm aceste șabloane, separate printr-o țeavă | . De exemplu, luni|marți|miercuri|joi|vineri|sâmbătă|duminică. Pentru ca lista de alternative să fie o unitate independentă și separată de cele învecinate, aceasta trebuie inclusă între paranteze. De exemplu, modelul Respected înseamnă șirul Respected urmat de unul dintre șirurile th sau th. Fără paranteze, modelul Dear|aya ar indica unul dintre șirurile Dear sau aya. Parantezele au un efect secundar important, care va fi discutat în secțiunea Grupare și capturare.

Pentru a indica de câte ori se poate repeta un model, așa-numitul cuantificatoare(din cuvântul latin cuantic- Câți):

Cuantificatori * , + și ? sunt redundante deoarece pot fi exprimate diferit folosind bretele. Și anume, * este echivalent cu (0,) , + este echivalent cu (1,) , nu? - la fel ca (0,1) . Dar acești cuantificatori sunt foarte des folosiți și, prin urmare, merită denumiri separate.

Dacă modelul căruia i se aplică cuantificatorul este ceva mai complex decât un singur caracter sau o singură clasă de caractere, acesta trebuie să fie cuprins între paranteze.

Aici sunt cateva exemple:

    ^\d+$ - o secvență de una sau mai multe cifre zecimale (un model pentru numere întregi nenegative în notație zecimală);

    ^\-?\d+$ - același lucru, dar pentru toate numerele întregi (eventual negative);

    ^\-?(\d+(\.\d*)?|\.\d+)$ - model pentru numere reale;

Să ne uităm la ultimul exemplu mai detaliat. Pe lângă semnul minus opțional de la început, modelul conține un grup cu două alternative: \d+(\.\d*)? și \.\d+ . Prima alternativă include o parte întreagă necesară \d+ (cel puțin o cifră), urmată de o parte fracțională opțională (\.\d*)? . Partea fracțională, dacă există una, are un punct zecimal și, eventual, mai multe cifre. Astfel, această alternativă corespunde liniilor 15, 15., 15.487. O altă alternativă este necesară pentru șiruri precum .618 cu lipsă întreaga parte- In multe limbaje informatice această postare are dreptul de a exista.

Dacă cele mai simple elemente ale unei expresii regulate - caractere, clase de caractere și ancore - sunt scrise într-un rând, aceasta înseamnă că atunci când un model este căutat într-un șir, aceste elemente vor fi potrivite cu părți ale șirului secvențial, în aceeași secvență . Acest ordin este încălcat dacă se aplică alternative. Vă puteți imagina că o expresie regulată compusă este formată din expresii simple folosind două operații: îmbinare secvențială ( compozitii) și alternative. Compoziția este un analog al operației de înmulțire din aritmetică. O alternativă este un analog al adăugării. Prima asemănare cu aritmetica este că operația alternativă are o prioritate mai mică decât compoziția, așa că pot fi necesare paranteze de grupare, ca în exemplul Dear.

Notă

Multe, deși nu toate, legi ale aritmeticii se aplică și expresiilor regulate:

comutativitatea alternativei x | y = y | X ; asociativitatea alternativei x | y | x și |

z = x ⁣ y |

x ⁣ z , x |

y z = x z |

yz .

În această ciudată aritmetică a expresiilor regulate, legea comutativității pentru compoziție nu este valabilă. În plus, nu există un analog de zero datorită relației evidente x | x = x . Rolul de unitate (dreapta și stânga) pentru compoziție este jucat de un șablon gol (să-l notăm 𝟙): 𝟙 ⁣ x = x ⁣ 𝟙 = x. Cuantificatorii de forma ( n ) joaca rolul de a ridica la a n-a putere.

Pe lângă funcția de grupare, parantezele îndeplinesc o funcție de captare. Principalul rezultat al potrivirii unui șir cu un model este răspunsul la întrebarea: șirul se potrivește cu modelul? Dar, în plus, este adesea necesar să se determine ce fragment sau fragmente dintr-un șir se potrivesc cu anumite fragmente într-o expresie regulată. Sau poate acid etilendiamină-N N N ′ N ′-tetraacetic? Să luăm în considerare un exemplu în care în text se găsesc referiri la diferiți acizi. Amintirile noastre de școală din chimie ne-au condus la ideea că numele acizilor se termină fie în vaya, fie naya, fie taya și apoi, după un spațiu, urmează cuvântul acid. Facem un șablon: \S+[int]acid. Potrivim textul cu șablonul. Noroc! Dar, cineva se întreabă, ce fel de acid a fost menționat în text? Sărat? Sulf? Azot? Plavikova? Clor? Cloric? Ipocloros? Lămâie? Sinilnoy? Dezoxiribonucleic?

2 4 5 ┝┑ ┝┑┝┑ (()(()())) │ ┝━━━━┙│ │ 3 │ ┝━━━━━━━━┙ 1

Dacă se dorește, un grup poate fi exclus din numerotare, adică lipsit de funcția sa „agresivă”, lăsând doar funcția de grupare. Pentru a face acest lucru, în loc de delimitatori de grup (⋯), folosim ( ?: ⋯) . Aici semnul întrebării Nu denotă un cuantificator deoarece cuantificatorul trebuie să fie precedat fie de un caracter, de o clasă de caractere, fie de un grup.

Utilizarea grupurilor de captură numerotate nu este întotdeauna convenabilă, mai ales în expresiile regulate mari. Doar introduceți-l în șablon grup nou captura, pe măsură ce numerotarea se pierde. Apoi va trebui să faceți corecții în toate locurile din program unde se accesează bufferele de captură după număr. Cu toate acestea, puteți asocia un nume cu un grup care vă permite să accesați tamponul corespunzător cu acel nume. Pentru a crea un grup numit, utilizați delimitatori ( ? ⋯) , unde numele dorit este înlocuit cu numele.

Părțile unui șir capturate în buffer-uri pot fi utilizate în două moduri. În primul rând, un program care utilizează o expresie regulată pentru a găsi sau înlocui se poate referi la buffer-uri ca variabile speciale. Această utilizare va fi discutată în secțiunea „Căutare și înlocuire operatori”. A doua posibilitate presupune utilizarea link-urilor către grupuri direct într-o expresie obișnuită, vezi secțiunea „Backlink-uri”.

Luați în considerare problema găsirii cuvintelor care conțin trei litere vocale identice la rând. Soluția naivă [аеооуеуя](3) folosind cuantificatori nu va funcționa, deoarece acest model se potrivește șiruri cu trei vocale consecutive, dar nu neapărat aceleași. Respingem cu indignare soluția monstruoasă cu o listă completă de alternative, aaa|eeee|yoyo|iii|oooo|uuu|eeee|yuyuyu|yayay: la urma urmei, merită să luăm o altă clasă simbolică, mai extinsă, sau să înlocuim triplul în cuantificator cu valoare mai mare, deoarece dimensiunea șablonului va crește catastrofal.

Tot posibil solutie eleganta, folosind grupuri de captură. Să captăm vocala într-un grup și apoi să facem referire la conținutul tamponului de capturare. Referințele la primul, al doilea, al treilea buffer sunt scrise într-o expresie regulată ca \g1, \g2, \g3. Deci, soluția este modelul ([aeeioueyuya])\g1(2) . Vă rugăm să rețineți că referința la tamponul de captare trebuie să vină strict după grupul corespunzător din expresia regulată.

Backlink-uri se poate referi nu numai la tampoane numerotate, ci și la cele numite. Astfel de legături arată ca \k , unde, din nou, în loc de nume există un nume specific. Exemplul nostru poate fi rescris folosind grupuri numite: (? [aeeyoooeyya])\k {2} (vocală- vocală).

Uneori este nevoie de o căutare care să nu facă distincția între litere mici și cu litere mari. Această căutare se numește insensibil la majuscule (insensibil la majuscule). În loc să înlocuim literele peste tot în model cu clase de două litere (a → , b → , ...), pur și simplu includem modelul în grup special, activând modul de căutare fără majuscule: (? eu:⋯) . Un astfel de grup nu este un grup de captură. Dacă căutarea care nu ține seama de majuscule și minuscule trebuie implementată doar pe o parte a expresiei regulate, atunci numai partea necesară ar trebui plasată în grup.

Dimpotrivă, dacă o parte a expresiei regulate în care se efectuează căutarea fără diferențiere între majuscule și minuscule trebuie să dezactiveze acest mod, atunci puteți reveni la căutarea obișnuită, care diferențiază majuscule și minuscule folosind grupul ( ?-i: ⋯) .

Modurile sensibile la majuscule/minuscule afectează numai literele. Ceea ce contează ca o literă și ce nu depinde de limbă, la fel și regulile de potrivire a literelor mari și mici. Din punctul de vedere al limbii engleze, de exemplu, simbolul Ш nu este o literă În limba germană există litera ß (apropo, versiunea majusculă a acestei litere este formată din două litere SS: Carl Friedrich Gauß. → CARL FRIEDRICH GAUSS).

Cheat sheet este un ghid general pentru modelele de expresie regulată, fără a ține cont de specificul oricărei limbi. Se prezinta sub forma unui tabel care incape pe o singura coala tiparita de format A4. Creat sub o licență Creative Commons bazată pe o fișă de trucuri creată de Dave Child ().

sa nu uiti asta diverse limbi Programele de programare acceptă expresii regulate în diferite grade, așa că este posibil să întâlniți o situație în care unele dintre caracteristicile afișate nu funcționează. Pentru cei care tocmai se familiarizează cu expresiile obișnuite, este oferită această traducere a comentariilor autorului la foaia de cheat. Vă va prezenta câteva dintre tehnicile utilizate în construirea modelelor de expresie regulată.

Ancorele din expresiile regulate indică începutul sau sfârșitul a ceva. De exemplu, rânduri sau cuvinte. Ele sunt reprezentate prin anumite simboluri. De exemplu, trebuie să aibă un model care se potrivește cu un șir care începe cu un număr următoarea vedere:

Aici caracterul ^ indică începutul liniei. Fără el, modelul s-ar potrivi cu orice șir care conține o cifră.

Clasele de caractere din expresiile regulate se potrivesc simultan cu un anumit set de caractere. De exemplu, \d se potrivește cu orice număr de la 0 la 9 inclusiv, \w se potrivește cu litere și cifre și \W se potrivește cu toate caracterele, altele decât literele și cifrele. Modelul de identificare a literelor, numerelor și spațiului arată astfel:

POSIX

POSIX este o adăugare relativ nouă la familia expresiilor regulate. Ideea, ca și în cazul claselor de caractere, este de a folosi comenzi rapide care reprezintă un anumit grup de caractere.

Aproape toată lumea are probleme în a înțelege afirmațiile la început, dar pe măsură ce vă familiarizați cu ele, vă veți descoperi că le utilizați destul de des. Afirmațiile oferă o modalitate de a spune: „Vreau să găsesc fiecare cuvânt din acest document care include litera „q” și nu este urmat de „werty”.

[^\s]*q(?!werty)[^\s]*

Codul de mai sus începe prin căutarea altor caractere decât spațiu ([^\s]*) urmate de q . Analizatorul ajunge apoi la o afirmație orientată spre viitor. Acest lucru face automat elementul precedent (caracter, grup sau clasă de caractere) condiționat - se va potrivi cu modelul numai dacă afirmația este adevărată. În cazul nostru, afirmația este negativă (?!), adică va fi adevărată dacă nu se găsește ceea ce se caută în ea.

Deci, analizatorul verifică următoarele câteva caractere cu modelul propus (werty). Dacă sunt găsite, atunci afirmația este falsă, ceea ce înseamnă că caracterul q va fi „ignorat”, adică nu se va potrivi cu modelul. Dacă nu se găsește werty, atunci afirmația este adevărată și totul este în ordine cu q. Apoi căutarea continuă pentru orice alt caracter decât spațiu ([^\s]*).

Acest grup conține modele de șabloane. Cu ajutorul lor, puteți vedea cum expresiile regulate pot fi folosite în practica zilnică. Cu toate acestea, rețineți că acestea nu vor funcționa neapărat în fiecare limbaj de programare, deoarece fiecare are propriile caracteristici unice și diferite niveluri Sprijin pentru expresia regulată.

Cuantificatorii vă permit să definiți o parte a unui model care trebuie repetat de mai multe ori la rând. De exemplu, dacă doriți să aflați dacă un document conține un șir de 10 până la 20 (inclusiv) de litere „a”, atunci puteți utiliza acest model:

A(10,20)

În mod implicit, cuantificatorii sunt „lacomi”. Prin urmare, cuantificatorul +, adică „de una sau mai multe ori”, va corespunde valorii maxime posibile. Uneori, acest lucru provoacă probleme, iar apoi puteți spune cuantificatorului să nu mai fie lacom (deveni „leneș”) folosind un modificator special. Uită-te la acest cod:

".*"

Acest model se potrivește cu textul cuprins între ghilimele duble. Cu toate acestea, linia sursă ar putea fi cam așa:

Salut Lume

Șablonul de mai sus va găsi următorul subșir în această linie:

"helloworld.htm" title="Buna ziua lume" !}

S-a dovedit a fi prea lacom, captivant cea mai mare bucată text care ar putea.

".*?"

Acest model se potrivește și cu orice caractere cuprinse între ghilimele duble. Dar versiunea leneșă (observați modificatorul?) caută cea mai mică apariție posibilă și, prin urmare, va găsi fiecare subșir în ghilimele duble separat:

„helloworld.htm” „Hello World”

Expresii obisnuite folosiți câteva simboluri pentru a indica diverse părțișablon. Cu toate acestea, apare o problemă dacă trebuie să găsiți unul dintre aceste caractere într-un șir, la fel ca un caracter obișnuit. Un punct, de exemplu, într-o expresie regulată înseamnă „orice caracter, altul decât o întrerupere de linie”. Dacă trebuie să găsiți un punct într-un șir, nu puteți utiliza doar „ . » ca șablon - acest lucru va duce la găsirea aproape orice. Deci, trebuie să spuneți analizorului că acest punct ar trebui considerat un punct obișnuit și nu „orice caracter”. Acest lucru se face folosind un semn de evacuare.

Un caracter de escape care precede un caracter, cum ar fi un punct, face ca analizatorul să-și ignore funcția și să-l trateze ca pe un caracter normal. Există mai multe caractere care necesită o astfel de evadare în majoritatea șabloanelor și limbilor. Le puteți găsi în colțul din dreapta jos al foii de cheat ("Meta Simboluri").

Modelul pentru găsirea unui punct este:

\.

Alte caractere speciale din expresiile regulate se potrivesc cu elemente neobișnuite din text. De exemplu, rupturile de linie și tabulațiile pot fi tastate pe tastatură, dar sunt susceptibile de a încurca limbajele de programare. Caracterul de evacuare este folosit aici pentru a-i spune analizorului să trateze următorul caracter ca fiind special, mai degrabă decât o scrisoare obișnuită sau număr.

Substituția șirurilor este descrisă în detaliu în paragraful următor, „Grupuri și intervale”, dar existența grupurilor „pasive” ar trebui menționată aici. Acestea sunt grupuri care sunt ignorate în timpul înlocuirii, ceea ce este foarte util dacă doriți să utilizați o condiție „sau” într-un model, dar nu doriți ca acel grup să ia parte la înlocuire.

Grupurile și intervalele sunt foarte, foarte utile. Probabil că este mai ușor să începeți cu intervale. Acestea vă permit să specificați un set de caractere adecvate. De exemplu, pentru a verifica dacă un șir conține cifre hexazecimale (de la 0 la 9 și de la A la F), ați folosi un interval ca acesta:

Pentru a verifica contrariul, utilizați un interval negativ, care în cazul nostru se potrivește oricărui caracter, cu excepția numerelor de la 0 la 9 și a literelor de la A la F:

[^A-Fa-f0-9]

Grupurile sunt folosite cel mai adesea atunci când este necesară o condiție „sau” într-un model; când trebuie să faceți referire la o parte a unui șablon dintr-o altă parte a acestuia; și, de asemenea, atunci când înlocuiți șiruri.

Utilizarea „sau” este foarte simplă: următorul model caută „ab” sau „bc”:

Dacă într-o expresie regulată este necesar să se facă referire la oricare dintre grupurile precedente, ar trebui să folosiți \n , unde în loc de n înlocuiți un număr grupul dorit. Poate doriți un model care să se potrivească cu literele „aaa” sau „bbb” urmate de un număr și apoi de aceleași trei litere. Acest model este implementat folosind grupuri:

(aaa|bbb)+\1

Prima parte a modelului caută „aaa” sau „bbb”, combinând literele găsite într-un grup. Aceasta este urmată de o căutare pentru una sau mai multe cifre (+) și, în final, \1. Ultima parte a modelului face referire la primul grup și caută același lucru. Caută o potrivire cu textul deja găsit de prima parte a modelului, nu o potrivire cu acesta. Deci „aaa123bbb” nu va satisface modelul de mai sus, deoarece \1 va căuta „aaa” după număr.

Una dintre cele mai instrumente utileîn expresiile regulate este substituția șirurilor. Când înlocuiți text, puteți face referire la grupul găsit folosind $n . Să presupunem că doriți să evidențiați toate cuvintele „dorință” din text cu caractere aldine. Pentru a face acest lucru, ar trebui să utilizați o funcție de înlocuire a expresiei regulate, care ar putea arăta astfel:

Înlocuiește (model, înlocuire, subiect)

Primul parametru va fi ceva de genul acestui șablon (s-ar putea să aveți nevoie de mai multe caractere suplimentare pentru această funcție specifică):

([^A-Za-z0-9])(dorință)([^A-Za-z0-9])

Va găsi orice apariție a cuvântului „dorință” împreună cu caracterele anterioare și următoare, atâta timp cât acestea nu sunt litere sau cifre. Atunci înlocuirea ta ar putea fi așa:

$1$2$3

Acesta va înlocui întregul șir găsit folosind modelul. Începem să înlocuim cu primul caracter găsit (care nu este o literă sau un număr), marcându-l $1 . Fără aceasta, am elimina pur și simplu acest caracter din text. Același lucru este valabil și pentru sfârșitul înlocuirii ($3). La mijloc am adaugat Etichetă HTML Pentru stil îndrăzneț(desigur că puteți folosi CSS sau ), alocandu-le al doilea grup găsit folosind șablonul ($2).

Modificatorii de șabloane sunt utilizați în mai multe limbi, în special în Perl. Ele vă permit să schimbați modul în care funcționează analizatorul. De exemplu, modificatorul i face ca analizatorul să ignore cazurile.

Expresiile regulate în Perl sunt înconjurate de același caracter la început și la sfârșit. Acesta poate fi orice caracter (cel mai des este folosit „/”) și arată astfel:

/model/

Modificatorii sunt adăugați la sfârșitul acestei linii, astfel:

/model/i

În cele din urmă, ultima parte a tabelului conține meta caractere. Acestea sunt simboluri care au sens specialîn expresii regulate. Deci, dacă doriți să utilizați unul dintre ele ca personaj obișnuit, atunci trebuie să fie eliminat. Pentru a verifica prezența unei paranteze în text, utilizați următorul model:

Chiar îți mulțumesc. mai ales pentru clarificare. Cu placere :) multumesc mult. mulțumesc foarte mult! Mulțumesc Seria cool... apropo, traduc această serie din engleză (și o fac în format HTML), o puteți vedea pe site-ul meu: sitemaker.x10.bz. Există, de asemenea, o foaie de cheat pe HTML, care nu este aici. Mulțumesc. Ce zici de eliminarea primelor 10 caractere de orice fel, apoi va fi ceva text cu simboluri, iar apoi de la un anumit simbol va trebui să eliminați totul până la sfârșit. !? 2 lails: Expresiile regulate nu sunt necesare aici. Substr() și strpos() vă vor ajuta dacă vorbim despre PHP, sau despre analogii lor în alte limbi. A fost interesant să citesc despre declarații, treptat încep să înțeleg. Va fi mai clar astfel: http://pcreonline.com/OazZNu/ Bună. Vă rog să-mi spuneți de ce „afirmațiile retrospective” nu funcționează pentru mine în FireFox? Ajutorul Mozilla RegExp nu le are deloc, este chiar imposibil în Fox? =((( Buna dimineata
Dar încă nu există suficiente cunoștințe despre cum să eliminați granițele. As fi recunoscator pentru ajutorul tau.
Vă rog să-mi spuneți cum să setez o expresie regulată pentru a verifica (poate fi sau nu o potrivire)?

Cum să scrieți corect o expresie regulată care începe cu semnul egal, găsește orice text în interior și se oprește la semnul &
Aceste caractere nu sunt incluse în căutare, partea necesară a șirului începe și se termină cu ele...
Scriu în mai multe feluri, dar ca rezultat fie tot textul rămâne, dar semnele = și & dispar

Sau și rămâne la sfârșitul rândului...

Am citit despre dolar, nu elimină caracterul de la sfârșitul rândului
mic exemplu

var reg = /[^=]*[^&]/g
str.match(reg);

În mod logic, începem cu semnul egal și căutăm orice text /[^=]*

apoi ne oprim la semnul & [^&] fără a-l include în căutare și repetăm ​​căutarea mai mult până când îl ocolim complet /g

Nu funcționează... Returnează întregul șir
Bună seara, spune-mi cum să găsesc un număr mai mic de 20?

Multumesc baieti Multumesc pentru articol! Spuneți-mi, ce se întâmplă dacă trebuie să limitați introducerea parolei la numere și nu mai mult de 5 litere?
Dima @ 24 aprilie 2015
Raspuns:((?=.*\d)(?=.*)(?=(8,15))--- la sfarsit, in loc de 8, pune doar 5
Salutare tuturor, abia incep...
Imi puteti spune ce inseamna:
/^\w\w/a
V-aș fi foarte recunoscător) Bună ziua, spuneți-mi cum să enumerați toate numerele din această expresie, separate printr-un spațiu 9*2 Cheat sheet Divine! Am rezolvat toate întrebările :-) (M1)
(M2)

(M3)

(M4)

(M5)

Spune-mi cum să scriu o expresie pentru a afla unde apare în text Am decis să scriu o foaie de cheat sheet despre expresiile regulate. Poate într-o zi le voi uita. În plus, această postare poate fi considerată o continuare a seriei mele de tutoriale Perl. 1. Introducere Câteva cuvinte pentru cei care nu prea știu despre ce vorbim despre care vorbim

. Ați văzut vreodată măști de nume de fișiere - tot felul de *.html, nume de fișier.(txt|csv) și așa mai departe? Deci, expresiile regulate sunt aceleași „măști”, doar mai complexe. ÎN în mâini capabile expresiile regulate pot fi un instrument incredibil de puternic. Într-un fel sau altul, sunt folosite în 95% din scripturile mele.

Prin urmare, în ciuda faptului că toate exemplele din notă sunt scrise în Perl, informațiile furnizate vor fi utile și programatorilor care folosesc orice alt limbaj în munca lor. De exemplu, acest cod în PHP:

if (preg_match ("//" , $text ) ) (
// textul conține numere
) altfel (
// nu există numere în text
}

și acesta în Perl:

dacă ($text =~ // ) (
# textul conține numere
) altfel (

}

face acelasi lucru. După cum ați putea ghici din comentariile din cod, aici Control dacă șirul $text conține cel puțin o cifră.

2. Exemple simple

Ca întotdeauna, vom învăța din exemple. Paranteza patrataîn expresiile regulate înseamnă „unul dintre caracterele enumerate trebuie să fie aici”. De exemplu, expresia de mai sus se potrivește cu orice șir care conține cel puțin o cifră. Similar cu expresia se potrivește cu orice șir care conține cel puțin una dintre primele trei litere ale alfabetului latin. Pentru a reprezenta orice personaj, cu exceptia specificat, se utilizează intrarea [^abcdef], adică cu simbolul capacului imediat după paranteza pătrată de deschidere.

Să presupunem că trebuie să verificăm dacă un șir conține vreun caracter al alfabetului latin. Nu este în întregime convenabil să enumerați toate cele 26 de litere, nu-i așa? Mai ales pentru astfel de cazuri în expresiile regulate pe care le puteți folosi liniuță între paranteze drepte pentru a desemna un set ordonat de caractere. Expresie Orice șir care conține cel puțin o literă minusculă a alfabetului latin se va potrivi. Prin analogie, exemplul dat anterior cu numere poate fi scris mai pe scurt:

dacă ($text =~ // ) (
# textul conține numere
) altfel (
# nu există numere în text
}

Și încă câteva exemple:

dacă ($text =~ // ) (
# textul conține cifre și/sau litere mici
# potrivit: abc, ZZaZZ, ===17
# nu este potrivit: EPIC FAIL, @^*!@#
}

dacă ($text =~ /[^0-9]/ ) (
# textul conține alte caractere decât numere
# se potrivește: abc, 123abc456, 0x1111111111
# nu este potrivit: 123, 123456, 9999999999
}

dacă ($text =~ // ) (
# textul conține litere din alfabetul latin
# potrivit: ___Abba___, zyx
# nu este potrivit: 0123, ^_^
}

dacă ($text =~ // ) (
# textul conține numere și litere de la A la F
# potrivit: ***777***, DeadC0de, intel, 0_o
# nu este potrivit: Xor, wiki
}

Să complicăm sarcina. Acum trebuie să verificăm nu doar prezența sau absența anumite personaje, dar respectarea șirului de caractere cu un anumit format. Iată câteva exemple simple:

dacă ($text =~ /num=/ ) (
# potrivit: num=1, some_num=000, bebenum=2(&^*
# nu este potrivit: NUM=1, my_num=-1, num=abc
}

dacă ($text =~ / / ) {
# se potrivește:
#zzz zzz
#
# nu sunt adecvate:
#
#
}

Cititorul atent se va întreba ce este asta semnul plus este în ultima expresie regulată? Acest simbol înseamnă „unul sau mai multe caractere specificate înainte de acest plus”. Simbolul înseamnă aproape același lucru stea"din zero până la orice număr de caractere specificat înainte de asterisc.” De exemplu, expresia A+ va potrivi o secvență de unul sau mai multe caractere A și expresia * - orice număr de cifre, inclusiv niciuna.

Uneori, numărul de caractere trebuie specificat mai precis. Acest lucru se poate face folosind acolade. De exemplu, expresia {8} se potrivește cu orice succesiune de exact opt ​​cifre și cu expresia {3,8} — o secvență care conține de la 3 la 8 caractere ale alfabetului latin.

Este posibil ca numărul din a doua poziție să nu fie specificat. Adică expresia {3,} poate apărea și. Înseamnă „cel puțin trei litere mici Alfabetul latin.” Expresie {0,} complet similar cu asteriscul și {1,} - la care se adauga. Expresie {0,1} poate fi scris mai pe scurt folosind semnul întrebării.

Exemplu (nu cel mai simplu, dar interesant):

dacă ($text =~ // ) {
# se potrivește:
#dfgd dfgdfg
#
# nu sunt adecvate:
#
#
}

Dacă acest exemplu îți face creierul să fiarbă, este timpul să exersezi puțin cu expresiile obișnuite scriind programe de testare. Altfel de la lectură în continuare vei avea o mizerie în cap. Dacă totul este clar până acum, să mergem mai departe.

3. Cum se rupe o bucată de linie?

Simbol linie verticala (alias „pipe” sau doar „stick”) în expresiile regulate înseamnă „sau”. De exemplu, expresia {20}|{25} se potrivește cu toate șirurile care conțin 20 de caractere latine sau 25 de numere la rând. De obicei, acest simbol este folosit împreună cu parantezele , conceput pentru a grupa părți ale unei expresii regulate. Exemplu:

dacă ($filename =~ /backup(19|20)(2)-(2)-(2)/) {
# potrivit: backup2011-04-01, backup1999-01-13
# nu este potrivit: backup1873-12-12, backup2101-07-07
}

Parantezele au o altă funcție. Cu ajutorul lor, puteți rupe bucăți din liniile corespunzătoare. În PHP, rezultatul este stocat în variabila specificată de al treilea argument al funcției preg_match. În Perl, potrivirile pentru prima, a doua... a 9-a pereche de paranteze sunt stocate în variabilele $1, $2,..., $9. Dar este mai convenabil să folosiți această construcție:

dacă (my ($y, $m, $d) =
$filename =~ /backup((4))-((2))-((2))/) {
imprimare ;
}

Întrebarea este ce număr să caute o potrivire în tabloul returnat dacă expresia regulată conține cuibărit paranteze? Este simplu - potrivirile sunt returnate în aceeași ordine ca și parantezele de deschidere. Exemplu:

my $filename = „./dumps/backup2011-04-01.tgz”;
$filename =~ /backup((20|19)(2))-((2))-((2))/;
imprimați „$1, $2, $3, $4 \n";
# va afișa: 2011, 20, 04, 01

Uneori am dori să grupăm o parte a unei expresii, dar să nu o returnăm. Pentru a face acest lucru, imediat după paranteza de deschidere trebuie să scrieți succesiune de semn de întrebare și două puncte. Exemplu:

dacă (my ($y, $m, $d) =
$filename =~ /backup((?:20|19)(2))-((2))-((2))/) {
imprimare "an = $y, luna = $m, ziua = $d\n";
}

Parantezele pot fi urmate și de un semn de întrebare, plus sau asterisc, indicând faptul că constructul din paranteze este opțional, trebuie repetat de 1+ ori sau, respectiv, de 0+ ori. Utilizarea acoladelor după paranteze este, de asemenea, acceptabilă.

4. Începutul și sfârșitul liniei

Este adesea util să indicați într-o expresie regulată unde ar trebui să înceapă și/sau să se termine un șir. Primul se face folosind simbolul capacului la începutul expresiei, al doilea - folosind semnul dolarului la sfârșitul. Exemple:

dacă ($text =~ /^*/ ) (
# text care începe cu o cifră zecimală
# potrivit: 3, 801403, 6543bebebe
# nu este potrivit: 0275, -123, abc11111
}

dacă ($text =~ /^0x(1,8)$/ ) (
# număr hexazecimal în notație C
# potrivit: 0x5f3759df, 0xDEADBEEF
# nu este potrivit: 0x1234xxx, xxx0x5678, xxx0x9ABCxxx
}

Nu e greu, nu? Vă rugăm să rețineți că atunci când verificați câmpurile formularului web, argumentele funcției înainte de a le înlocui într-o interogare SQL etc. Neapărat ar trebui verificat toateșir, așa cum s-a făcut în ultima expresie regulată.

Notă: Dacă cineva este interesat de ce asta" numere magice» 0x5f3759df și 0xDEADBEEF, consultați Wikipedia.

5. Personaje speciale

Pe lângă cele menționate caractere speciale trebuie remarcat în mod deosebit punct. Ea vrea să spună orice alt caracter decât caracter linie nouă. Exemplu de utilizare:

dacă (meu ($numele ) = $arg =~ /^--numele=(.+)$/ ) (
printează „Bună ziua, $name! \n";
}

În mod implicit, expresiile regulate produc ceea ce se numește parsing lacom. Cu alte cuvinte, se caută meciuri lungime maxima. Când folosim un punct, acest lucru poate cauza probleme. De exemplu, trebuie să scoatem un text din sute de pagini HTML cu aproximativ următorul conținut:

<interval > Text<ei > text</em> text</span> Sursa: http://site/</span>

Următorul cod nu va returna ceea ce ne-am dori:

# expresia regulată conține o bară oblică, deci
# trebuie să folosească un alt delimitator
(.*)#;
print $text ;
# va imprima cea mai lungă potrivire:
#Text text textSource: http://site/

Iată ce se întâmplă dacă dezactivați analiza lacomă (rețineți semnul întrebării):

my ($text ) = $date =~ m # (.*?)#;
print $text ;
# va imprima prima potrivire:
#Text text text

Da, următoarele rânduri face acelasi lucru:

# intrare obișnuită...
$text =~ /({4})-({2})-({2})/ ;
# este de fapt doar o prescurtare pentru operatorul m//
$text =~ m/((4))-((2))-((2))/;
# în loc de bară oblică, puteți folosi diferite paranteze:
$text =~ m ( ([ 0 - 9 ] ( 4 ) ) - ( [ 0 - 9 ] ( 2 ) ) - ( [ 0 - 9 ] ( 2 ) ) ) ;
$text =~ m< ([ 0 - 9 ] { 4 } ) - ([ 0 - 9 ] { 2 } ) - ([ 0 - 9 ] { 2 } ) >;
$text =~ m [ ([ 0 - 9 ] ( 4 ) ) - ( [ 0 - 9 ] ( 2 ) ) - ( [ 0 - 9 ] ( 2 ) ) ] ;
$text =~ m (([ 0 - 9 ] ( 4 ) ) - ( [ 0 - 9 ] ( 2 ) ) - ( [ 0 - 9 ] ( 2 ) ) ) ;
# sau chiar simboluri ca acesta:
$text =~ m ! ([ 0 - 9 ] ( 4 ) ) - ( [ 0 - 9 ] ( 2 ) ) - ( [ 0 - 9 ] ( 2 ) ) !;
$text =~ m | ([ 0 - 9 ] ( 4 ) ) - ( [ 0 - 9 ] ( 2 ) ) - ( [ 0 - 9 ] ( 2 ) ) |;
$text =~ m #({4})-({2})-({2})#;
# precum și cap, ghilimele, două puncte, virgulă, punct, ...

De ce au fost necesare atât de multe moduri de a scrie expresii regulate? Imaginați-vă că expresia conține bare oblice, puncte, virgule și alte simboluri, dar nu conține un semn de exclamare. Apoi, evident, nu putem folosi bare oblice, puncte și așa mai departe pentru a indica începutul și sfârșitul unei expresii regulate, dar Semn de exclamare- Poate sa.

Adesea, în expresiile regulate trebuie să le folosiți backslash. Așezat înaintea unui punct, a unei paranteze, a unui plus, a unui capac și a altor simboluri, înseamnă „următorul simbol înseamnă exact simbolulși nu altceva.” De exemplu, iată cum să determinați o extensie de fișier după numele său:

# a scăpat backslash punct
# înseamnă un punct, nu „orice caracter”
my ($ext ) = $fname =~ /\.(+)$/ ;
imprimare "nume fișier: $fname, extensie: $ext\n";

În plus, bara oblică inversă este utilizată în următoarea notație:

  • \t— denotă un caracter tabulator ( t ab)
  • \rȘi \n- caractere de întoarcere la cărucior ( rîntoarcere) și linie nouă ( n linie nouă)
  • \xNN— potrivește un caracter cu codul ASCII NN, de exemplu \x41 corespunde majusculă A din alfabetul latin
  • \s- se potrivește cu un spațiu ( s ritm), filă, linie nouă sau întoarcere la cărucior
  • \d- înseamnă orice număr ( d igit), sau mai precis, ceea ce este considerat un număr în Unicode (vezi diapozitivul numărul 102 din această prezentare)
  • \w- înseamnă așa-numitul „cuvânt” ( w ord), analog

În ultimele trei expresii, scrierea literei cu litere mari înseamnă negație. De exemplu, \D corespunde expresiei [^0-9] , \W- expresie [^0-9a-zA-Z_], A \S- orice caracter „non-spațiu alb”.

Toate aceste expresii „litere” pot fi folosite între paranteze pătrate. De exemplu, expresia complet echivalent .

Expresiile merită o atenție deosebită \bȘi \B, adică granița unui cuvânt (în același sens de „cuvânt” ca și în cazul lui \w) și, respectiv, absența unei granițe de cuvânt. De exemplu, expresia perl\b se potrivește cu șirul „perl rulez!”, dar nu se potrivește cu „perlmonk”. Cu expresie perl\B totul este exact invers. Sper ca ideea sa fie clara.

Si inca un exemplu:

#spargere Numele complet calea și numele fișierului
my ($cale , $fname ) = $nume_complet =~ /^(.*)\/([^\/]+)$/ ;

Acesta ilustrează utilizarea barei oblice inverse pentru a scăpa de un caracter care este folosit pentru a denota limitele expresiilor regulate. ÎN în acest exemplu aceasta este o bară oblică înainte.

6. Modificatori

Comportamentul expresiilor regulate poate fi modificat folosind modificatori. De exemplu, după cum poate ați observat deja, potrivirea unui șir cu o expresie regulată este verificată ținând cont de majuscule și minuscule. Puteți modifica acest comportament folosind modificatorul # (.*?)#g;
# fii atent când folosești /g în context scalar
# detalii aici: http://koorchik.blogspot.com/2011/07/perl-5.html
tipăriți „$_ \n" pentru (@cuvinte);

După cum am menționat mai sus, un punct denotă orice caracter cu excepția caracterului newline. Puteți modifica acest comportament folosind un modificator /s:

# extrageți conținutul articolului din fișierul HTML,
# care poate conține mai mult de una sau două rânduri
meu ($articol) = $html =~ m #

(.*?)
#s;

Apropo, dacă într-o expresie obișnuită trebuie să indicați „orice caracter” fără a utiliza un modificator /s, folosiți expresia [\d\D]. Înseamnă „orice caracter care este o cifră sau nu este o cifră”, adică orice caracter.

În cele din urmă, nimic nu te împiedică să folosești mai mulți modificatori în același timp:

# scoateți totul cu caractere aldine din fișierul HTML
@cuvintele mele = $html =~ m # (.*?)#gi;
# va lucra pentru , sau chiar

Plus: Un alt modificator util este /o. Înseamnă „compilați expresia regulată o singură dată”. ÎN nisteÎn cazuri, acest modificator poate accelera semnificativ scriptul. Cu toate acestea, nu sunt sigur că este acceptat oriunde, în afară de Perl. Mulțumesc pentru bacșiș tovarăș

Secretele expresiilor regulate

Partea 1. Dialecte și capacități. Scrierea expresiilor regulate

Seria de conținut:

1. Introducere. Folosim expresiile regulate la potențialul lor maxim?

Dacă vă gândiți la întrebarea: „Ce este o „expresie obișnuită” în general?”, atunci răspunsul nu va fi găsit imediat. Putem spune că acesta este un limbaj specializat pentru descrierea unui model de caractere (secvență de caractere) pentru căutarea în șiruri de text. Lucrul important aici este că atunci când căutați potriviri, se realizează o comparație caracter cu caracter. Autorul enciclopediei despre expresiile regulate (Mastering Regular Expressions) Jeffrey Friedl (J.E.F. Friedl) sfătuiește dezvoltarea obiceiului de a interpreta expresiile regulate la propriu. De exemplu, privind modelul „^cat”, care înseamnă „linia trebuie să înceapă cu cuvântul pisică”, s-ar putea gândi că „se va găsi o potrivire dacă suntem la începutul liniei și găsim imediat caracterul c. urmat de caracterul a, imediat urmat de simbolul t”. Acest lucru vă permite să evaluați cel mai precis sensul și esența unei expresii regulate.

Majoritatea utilizatorilor știu că pentru a căuta, trebuie doar să introduceți un cuvânt eșantion. De exemplu, într-un browser Web, în ​​câmpul „Căutare”, după ce ați introdus „Linux”, veți primi o listă lungă de link-uri către pagini al căror text se potrivește cu modelul specificat „Linux”. În local Sistemul de fișiere utilizați comanda grep „Linux” sau instrumente grafice căutare.

Nu toți, dar mulți utilizatori știu să folosească metacaracterele (* . ?) în modelele de căutare. Și mai puțini oameni știu despre posibilitatea de a folosi modificatori și alte instrumente sofisticate pentru construirea expresiilor regulate, de ex. în multe cazuri, abia o treime din puterea motorului de expresie regulată este utilizată. De ce nu încercați să creșteți eficiența?

2. Diferite dialecte ale expresiilor regulate. Conformitate POSIX

În general, există două dialecte (sau tipuri) principale de expresii regulate: simple și extinse. În același timp, granița dintre ele este condiționată și devine din ce în ce mai puțin clară în timp.

Programele vi(m), sed, grep, less, ed, expr, lex înțeleg doar expresii regulate simple, în timp ce utilitarele (g)awk, egrep, precum și interpreții limbajelor Perl, Tcl, Python, înțeleg obișnuit extins. expresii. În același timp, fiecare dintre programe are propriile îmbunătățiri, adică. sunt create subdialecte ale expresiilor regulate. Să ne uităm la asemănările și diferențele dintre aceste dialecte.

2.1. Schema generală de expresie regulată

De obicei, o expresie regulată constă din trei părți principale:

  1. Ancoră – definește poziția șablonului într-o linie de text:
    • ^ – ancora care definește începutul liniei;
    • $ este o ancoră care definește sfârșitul liniei.
  2. Un set (secvență) de caractere – pentru a căuta potriviri în poziții date ale unei linii de text:
    • caracterul punct (.) se potrivește cu orice caracter arbitrar;
    • caracterele alfanumerice și spațiul se reprezintă;
    • alte simboluri – interpretarea depinde de dialect.
  3. Modificator – stabilește numărul de repetări ale caracterului sau al setului de caractere anterior (în funcție de dialect):
    • * – orice număr de repetări ale unui simbol/set, inclusiv zero;
    • ? – se potrivește cu zero sau o instanță a unui caracter/set;
    • + – corespunde unuia sau Mai mult instanțe de simbol/set.

Exemplu: trebuie să găsiți toate directivele de definire a constantelor macro în cod sursaîn limba S.

grep "^ *#define.*" *.c *.h

Aici se ține cont de faptul că la începutul liniei de definire a macrocomenzii poate fi introdus orice număr de spații sau niciun spațiu. Partea #define a șablonului este literală, adică. fiecare personaj este interpretat „ca atare”. Partea finală a șablonului înseamnă „orice simboluri în orice cantitate”.

Rețineți că caracterul ^ este interpretat ca o ancoră care marchează începutul unei linii numai dacă este primul caracter al modelului. În mod similar, caracterul $ marchează sfârșitul unei linii, cu condiția ca acesta să fie ultimul caracter al modelului. În toate celelalte cazuri, aceste simboluri devin literale, de exemplu. se reprezintă pe ei înșiși.

2.2. Definirea intervalelor de caractere în expresiile regulate

Dacă este nevoie să specificați un caracter dintr-un anumit grup, de exemplu, doar un caracter numeric, sau doar o vocală cu minuscule, sau doar simboluri de punctuație, atunci se folosesc paranteze pătrate, în care sunt definite caracterele necesare. Prin urmare:

  • – corespunde unui caracter digital dintr-un set dat;
  • [аееоуыеюя] – corespunde uneia dintre vocalele enumerate;
  • [,.:;] – se potrivește cu unul dintre simbolurile de punctuație.

Vă rugăm să rețineți că, în acest din urmă caz, punctul dintre paranteze pătrate își pierde statutul special și denotă nu „orice caracter”, ci caracterul „punct” în sine.

Intervalele continue de caractere pot fi scrise sub formă scurtă folosind o cratimă: primul exemplu este mai convenabil scris ca . În plus, este permisă orice combinație de intervale și caractere specifice.

De asemenea, este posibil să excludeți seturi de caractere specificate din căutare, care se face după cum urmează:

  • [^0-9] – se potrivește cu orice caracter, cu excepția cifrelor;
  • [^аеойоуыеюя] – se potrivește cu orice literă care NU este o vocală.

Ne vom familiariza cu alte nuanțe de definire a intervalelor de caractere între paranteze drepte în procesul de aplicare, iar acum vom lua în considerare modificatorii folosind exemplul unui model de căutare pentru o adresă IP digitală.

2.3. Modificatori pentru numărul de repetare a caracterelor

Dificultatea aici este că modificatorul * nu este potrivit pentru căutarea unei adrese IP - o încercare de a utiliza modelul *\.*\.*\. va avea ca rezultat linii care conțin elemente de tip 2344.5657.11.00000, care nu sunt adrese IP. Pentru a specifica numărul de repetări ale seturilor de caractere, se folosește modificatorul \(min,max\). Știind că fiecare parte a unei adrese IP poate conține de la una la trei cifre, scriem modificatorul sub forma \(1,3\). Caracterele bară oblică inversă înainte de puncte sunt necesare pentru a le anula statut special metacaracter universal. De asemenea, rețineți că valoarea 0 nu este folosită ca primul octet al adreselor IP obișnuite. Ca rezultat, obținem următorul model de căutare:

grep "\(0,2\)\.\(1,3\)\.\(1,3\)\.\(1,3\)" *.txt

Modificatorul \(min,max\) funcționează numai în expresiile regulate simple. Nu puteți folosi \( \) în expresiile regulate extinse, dar puteți folosi un modificator? ca echivalent al expresiei \(0,1\), iar modificatorul + ca echivalent al expresiei \(1,\). În al doilea caz, punctul zecimal nu este specificat valoare numerica- înseamnă că suma maxima meciurile sunt nelimitate.

2.4. Memorarea și reutilizarea unui element șablon

Acest mecanism funcționează, de asemenea, numai în expresii regulate simple. (Cu toate acestea, în limbajele de programare Perl, Python etc., acest mecanism este acceptat - granița dintre dialecte devine din ce în ce mai puțin distinsă, vă amintiți?)

În expresiile regulate simple, părțile modelului incluse în construcția \(\) sunt reținute și numerotate, după care pot fi reutilizate. În total, puteți memora până la nouă modele numerotate. Cel mai ilustrativ exemplu de utilizare a mecanismului de memorare este căutarea palindromilor (cuvinte care se citesc la fel atât de la stânga la dreapta, cât și de la dreapta la stânga):

  • \(\)\(\)\2\1 – pentru palindromuri cu cinci litere (de exemplu, nivel, rotor, doamnă etc.)
  • \(\)\(\)\(\)\3\2\1 – pentru palindromuri cu șase litere (de exemplu, redder, succus, terret etc.)

2.5. Conformitate POSIX

De asemenea, standardul POSIX împarte expresiile regulate în două categorii: BRE (Expresii regulate de bază) și ERE (Expresii regulate extinse). Metacaracterele sunt acceptate în ambele categorii. și *, ancore ^ și $, grupând caracterele în paranteze (pentru BRE, parantezele sunt scăpate cu o bară oblică inversă), aplicând cuantificatori \(min,max\) la grupurile din paranteze. Memorare și reutilizare\1...\9 acceptă numai categoria BRE, iar cuantificatorii + și? și constructul de alegere – numai categoria ERE.

ÎN Standardul POSIX Se folosește conceptul de context local (locale) - un set de parametri care descriu regulile lingvistice și culturale: formatul datei și orei, interpretarea caracterelor de codificare active etc. Acest lucru nu se aplică direct expresiilor regulate, dar afectează modul în care acestea funcționează. Când se lucrează într-un context local cu codificare UTF-8, adoptată în aproape toate distribuțiile moderne, caracterele alfabetului rus și intervalele lor sunt procesate corect, de exemplu. Puteți specifica intervalele [a-z] și [A-Z] în șabloanele de căutare.

3. Exemple de compunere a expresiilor regulate utile

Pentru a crea expresii regulate care funcționează corect, teoria nu este suficientă. Este necesar să învățați nu numai să construiți și să scrieți un șablon, ci și să luați în considerare pe deplin contextul în care va fi comparat. Scrierea și îmbunătățirea unui șablon este un proces iterativ, în timpul căruia se rezolvă două sarcini principale: pe de o parte, să obțină toate liniile necesare, fără a le rata pe cele care, conform planului, ar fi trebuit să se potrivească, dar din anumite motive nu s-au potrivit. Meci; pe de altă parte, excludeți totul linii inutile, inclusiv cele care, conform planului, ar trebui aruncate, dar din anumite motive au coincis.

3.1. Un exemplu de șablon pentru căutarea unei sume de bani scrise în formatul „10.000 de ruble 00 de copeici”.

\(1,\) freca\. \(2\) copeici\.

Clarificare necesară: dacă unui modificator precum \(min,max\) îi lipsește atât o virgulă, cât și o valoare maximă, atunci această construcție specifică numărul exact de repetări așteptate ale elementului șablon. În exemplul nostru, exact două caractere digitale sunt definite pentru a reprezenta copeici.

3.2. Un exemplu de șablon pentru căutarea unui șir URL corespunzător unei resurse Web de pe Internet:

http://\(1,\)\.[-a-zA-Z0-9_]\(1,\)/*

Clarificare necesară: o cratima își pierde semnificația specială dacă este specificată în prima poziție imediat după deschidere paranteza pătratăîn intervalul. De acest șablonșirurile URL „exotice” precum, de exemplu, http://my.home-server/ pot fi găsite și

În formatul de expresie regulată extins, acest model ar putea fi scris mai compact:

http://+\.[-a-zA-Z0-9_]+/*

Această notație este înțeleasă, de exemplu, de utilitățile egrep și awk.

3.3. Șablonul pentru căutarea oricărei etichete HTML pare surprinzător de simplu:

<[^>]+>

Se potrivește cu orice succesiune de caractere, cu excepția unuia sau mai multor > cuprinse între paranteze unghiulare. Cu alte cuvinte, va fi găsită și o etichetă cu un singur caracter

Și etichete mai detaliate precum


.

3.4. Opțiune de șablon pentru căutarea datelor

Expresiile regulate avansate vă permit să scrieți un șablon oarecum greoi, dar care funcționează corect, pentru căutarea unor date care arată ca „13 noiembrie 2009”:

? (Ian|Feb|Mar|Apr|Mai|Iun|Iul|Aug|Sep|Oct|Nov|Dec).* g\.

Dezavantajul acestui model este că nu poate fi folosit pentru a găsi date din istoria antica, de exemplu, „13 noiembrie 245”. sau 1 ianuarie 88”, dar este destul de potrivit pentru lucrul cu documente moderne (ține cont de contextul de căutare!).

3.5. Aplicarea practică a părților numerotate ale șablonului

În secțiunea anterioară, am dat deja un exemplu de șablon pentru căutarea palindromilor. Funcționalitatea sa poate fi, de asemenea, îmbunătățită ușor prin rescrierea expresiei după cum urmează:

\(.\)\(.\)\(.\)\3\2\1

Folosind acest șablon, puteți găsi palindromuri cu șase caractere nu numai în engleză, ci și în rusă și în orice alte limbi, precum și secvențe de caractere non-alfabetice, de exemplu /*!!*/

O modalitate mai practică de a utiliza părțile reținute și numerotate ale unui model este căutarea stând în apropiere repetarea cuvintelor, ceea ce face posibilă detectarea unor astfel de erori comune (greșeli de scriere) în texte precum „pentru pentru”. Modelul poate fi scris astfel:

\<\(..*\)\> \<\1\>

Încă două elemente de expresie regulată sunt folosite aici: \< для обозначения начальной границы слова и \>pentru a indica limita finală a unui cuvânt. Astfel, ne amintim doar cuvinte individuale, și nu orice succesiune de caractere. Expresia ..* se potrivește cu orice cuvânt format din cel puțin un caracter. În consecință, vom putea găsi greșeli de scriere repetate precum „și și”, „nu nu”, „pentru pentru”, etc.

3.6. Limitarea dimensiunii părții potrivite a modelului

O altă caracteristică a „caracterului” expresiilor regulate este că sunt incredibil de „lacomi”, adică. străduiți-vă să egalați cât mai multe linie lunga. Din cauza acestei „lacomie” pot apărea probleme neașteptate. De exemplu, există un model pentru căutarea oricărui număr de caractere cuprinse între ghilimele:

".*"

Șirurile de căutare arată astfel:

„Petrov” „paznicul” „Ivanov” „departamentul de aprovizionare” „expediciórul” „Sidorov” „administrație” „director”

Dacă sarcina a fost de a extrage doar primul argument (numele de familie al angajatului) din șirurile date, atunci șablonul propus mai sus nu îl va executa corect, deoarece al doilea ghilimeleu al șablonului se potrivește cu ultimul ghilibat al șirului (datorită dorinței pentru a obține potrivirea maximă). Schimbarea șablonului:

".*" ".*"

rezolvă problema doar pentru prima linie, iar în a doua și a treia locul de muncă este și el atașat numelui de familie - din nou, nu ceea ce ne trebuie!

Această problemă poate fi rezolvată corect folosind o expresie regulată care se potrivește cu cea mai scurtă dintre toate fragmentele de șir posibile, situate între două ghilimele:

"[^"]*"

Aici, ghilimele de deschidere trebuie să fie urmate de orice număr de caractere fără ghilimele până când se întâlnește ghilimele de sfârșit.

4. Concluzie

Chiar și din exemplele, care au fost departe de a fi cele mai complexe, care au fost descrise în acest articol, ați putut înțelege cât de bogate și variate sunt capabilitățile expresiilor regulate. Puteți lua în considerare chiar și formatul de înregistrare al șabloanelor lor limbaj deosebit programare, învățând să gândiți și să scrieți în care, vă veți salva de cantitate mare muncă monotonă și plictisitoare.

Primul articol a oferit o idee generală despre expresiile obișnuite și domeniul lor, precum și scurtă recenzie caracteristici ale dialectelor lor. Au fost luate în considerare exemple de compunere a expresiilor regulate pentru a rezolva diverse probleme.

Continuarea seriei va fi dedicată munca practica cu expresii regulate în programe specifice și medii de limbaj.

Resurse pentru descărcare

static.content.url=http://www.site/developerworks/js/artating/

ID articol=487264

ArticleTitle=Secretele expresiilor regulate: Partea 1. Dialecte și capabilități. Scrierea expresiilor regulate