Grupurile în expresiile regulate
Definirea grupurilor în expresiile regulate
Pentru a căuta corespondențe mai complexe într-un șir, se utilizează grupurile în expresiile regulate. Grupurile sunt delimitate de paranteze. De exemplu, să presupunem că dorim să obținem o dată într-un anumit format. Cu ajutorul metodei exec() a obiectului RegExp, putem obține întreaga potrivire.
Să zicem că data este reprezentată în formatul "yyyy-mm-dd" (2021-09-06):
const exp = /\d{4}-\d{2}-\d{2}/;
const text = "Publication Date: 2021-09-06"
const result = exp.exec(text);
console.log(result[0]); // 2021-09-06
Din rezultatul metodei exec, putem extrage rezultatul - data dorită. Totuși, ce facem dacă dorim să obținem componente individuale ale datei - anul, luna, ziua? În acest caz, putem folosi grupurile.
Fiecare grup reprezintă o parte a expresiei regulate și este înconjurat de paranteze rotunde. De exemplu:
const exp = /(\d{4})-(\d{2})-(\d{2})/;
const text = "Publication Date: 2021-09-06"
const result = exp.exec(text);
console.log(result);
// Afișaj în consolă
// (4) ['2021-09-06', '2021', '09', '06', index: 18, input: 'Publication Date: 2021-09-06', groups: undefined]
Aici, expresia regulată /(\d{4})-(\d{2})-(\d{2})/ conține trei grupuri. Primul grup - (\d{4}) constă din 4 cifre și reprezintă anul. Al doilea grup - (\d{2}) constă din 2 cifre și reprezintă luna. Al treilea grup, de asemenea, constă din 2 cifre și reprezintă ziua.
Această expresie regulată "/(\d{4})-(\d{2})-(\d{2})/" are trei grupuri definite:
- Prima grupă (\d{4}) se potrivește cu un număr format din patru cifre.
- A doua grupă (\d{2}) se potrivește cu un număr format din două cifre.
- A treia grupă este similară cu a doua.
Și dacă ne uităm la rezultatul metodei exec(), vom vedea că, în afară de potrivirea efectivă cu data, el conține potriviri pentru fiecare grupă în parte:
(4) ['2021-09-06', '2021', '09', '06', index: 18, input: 'Publication Date: 2021-09-06', groups: undefined]
Rezultatul obținut reprezintă un array, unde primul element (cu indexul 0) reprezintă întotdeauna subșirul care se potrivește cu expresia regulată. Toate elementele ulterioare ale acestui array reprezintă grupurile.
Prin urmare, prima grupă are indexul 1, a doua are indexul 2 și așa mai departe. Prin aplicarea acestor indici, putem obține toate potrivirile grupelor din expresia regulată:
const exp = /(\d{4})-(\d{2})-(\d{2})/;
const text = "Publication Date: 2021-09-06"
const result = exp.exec(text);
console.log(result[0]); // 2021-09-06 - potrivirea completă
console.log(result[1]); // 2021 - prima grupă
console.log(result[2]); // 09 - a doua grupă
console.log(result[3]); // 06 - a treia grupă
Prin obținerea valorilor grupelor individuale, se pot realiza anumite acțiuni cu acestea, cum ar fi transformarea lor în alt format de dată:
console.log(`${result[3]}.${result[2]}.${result[1]}`); // 06.09.2021
Gruparea simplifică crearea expresiilor regulate mai complexe. La fel ca și în cazul caracterelor individuale, la grupuri le pot fi aplicate cuantificatoare. De exemplu, expresia (la)+ reprezintă una sau mai multe repetări ale șirului "la".
Grupuri denumite
JavaScript permite asignarea unui nume fiecărei grupe în expresiile regulate. Cu ajutorul acestui nume, se poate obține ulterior valoarea care corespunde acestei grupe.
Pentru a atribui un nume grupului în interiorul parantezelor care definesc grupa, se adaugă un semn de întrebare, iar apoi între parantezele unghiulare se introduce numele grupului:
(?<nume_grup> ... )
Să analizăm exemplul următor:
const exp = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const text = "Publication Date: 2021-09-06"
const result = exp.exec(text);
console.log(result.groups); // {year: "2021", month: "09", day: "06"}
console.log(result.groups.year); // 2021
console.log(result.groups.month); // 09
console.log(result.groups.day); // 06
Aici, expresia regulată definește trei grupuri. Prima grupă se numește "year", a doua - "month", iar a treia - "day". Când obținem rezultatul, putem accesa fiecare grupă prin intermediul proprietății groups.
Această proprietate reprezintă un obiect în care proprietățile au aceleași nume ca și grupurile și conțin valorile pentru fiecare grupă:
console.log(result.groups); // {year: "2021", month: "09", day: "06"}
Prin urmare, utilizând numele grupelor, putem obține valoarea pentru fiecare grupă în parte.
Afirmații
Afirmațiile permit obținerea unui subșir care se potrivește cu o expresie regulată și care este precedat sau, dimpotrivă, nu este precedat de o anumită expresie.
Afirmarea pozitivă (când subșirul trebuie să fie precedat de alt subșir) este definită cu ajutorul expresiei:
(?<=...)
După semnul egal = urmează expresia cu care subșirul trebuie să fie precedat.
Afirmarea negativă (când subșirul NU trebuie să fie precedat de alt subșir) este definită cu ajutorul expresiei:
(?<!...)
După semnul exclamării ! urmează expresia cu care subșirul nu trebuie să fie precedat.
Hai să luăm o sarcină simplă. Să presupunem că avem o anumită informație cu o anumită sumă. Dar această sumă poate fi exprimată în dolari, euro, gbp etc. Ceva asemănător:
const text1 = "All costs: $10.53";
const text2 = "All costs: €10.53";
const exp = /\d+(\.\d*)?/;
const result1 = exp.exec(text1);
console.log(result1[0]); // 10.53
const result2 = exp.exec(text2);
console.log(result2[0]); // 10.53
Aici vedem că atât suma în dolari (\\$) cât și suma în euro (€) corespund expresiei regulate. Dar ce facem dacă dorim să obținem doar suma în dolari? Pentru asta, vom aplica o afirmare pozitivă:
const text1 = "All costs: $10.53";
const text2 = "All costs: €10.53";
const exp = /(?<=\$)\d+(\.\d*)?/;
const result1 = exp.exec(text1);
console.log(result1); // ["10.53", ".53", index: 12, input: "All costs: $10.53", groups: undefined]
const result2 = exp.exec(text2);
console.log(result2); // null
Grupa (?<=\$) indică că înaintea șirului trebuie să existe simbolul dolar $. Dacă acesta lipsește, atunci metoda exec() nu va găsi nicio potrivire și va returna null.