53. Wyrażenia regularne

Wprowadzenie do wyrażeń regularnych

Wyrażenia regularne (ang. *regular expressions*, w skrócie *regex*) to potężne narzędzie służące do wyszukiwania, dopasowywania i manipulowania tekstem na podstawie określonych wzorców. Są one nieocenione w walidacji danych, przetwarzaniu tekstu oraz parsowaniu informacji. Dzięki wyrażeniom regularnym można precyzyjnie definiować, jakie ciągi znaków są akceptowalne, a które nie.

Podstawowe elementy wyrażeń regularnych

Wyrażenia regularne składają się z kombinacji znaków specjalnych i literałów. Oto kilka podstawowych elementów:

  • Literały: Dopasowują dokładnie dany znak, np. a dopasuje małą literę "a".
  • Klasy znaków: np. [a-z] dopasowuje małe litery od "a" do "z", a \d dowolną cyfrę.
  • Kwantyfikatory: Określają, ile razy dany wzorzec może wystąpić:
    • * – zero lub więcej razy,
    • + – jeden lub więcej razy,
    • ? – zero lub jeden raz,
    • {n} – dokładnie n razy.
  • Specjalne znaki: np. . dopasowuje dowolny znak (oprócz nowej linii), \s dopasowuje białe znaki.
  • Grupy: Nawiasy okrągłe () służą do grupowania wzorców, np. (ab)+ dopasowuje "ab", "abab", itd.
Twórca wyrażeń regularnych

Wyrażenia regularne tworzy się za pomocą obiektu RegExp lub notacji literałowej. Oto dwa sposoby:

// Notacja literałowa
const regex1 = /wzorzec/;

// Konstruktor RegExp
const regex2 = new RegExp("wzorzec");

Można również używać flag, które modyfikują zachowanie wyrażenia regularnego:

  • i – ignorowanie wielkości liter,
  • g – globalne dopasowanie (wszystkie wystąpienia),
  • m – wieloliniowe dopasowanie.
const regex = /wzorzec/gi; // Ignoruje wielkość liter i szuka wszystkich wystąpień
Metody pracy z wyrażeniami regularnymi

W JavaScript istnieje kilka metod do pracy z wyrażeniami regularnymi:

  • test() – sprawdza, czy dany tekst pasuje do wzorca (zwraca true lub false).
  • exec() – zwraca tablicę z dopasowaniami lub null, jeśli brak dopasowania.
  • match() – metoda obiektu String, która zwraca tablicę dopasowań.
  • replace() – metoda obiektu String, która zastępuje dopasowane fragmenty tekstu.
  • search() – metoda obiektu String, która zwraca indeks pierwszego dopasowania.
Przykład: Użycie metody test()
const regex = /abc/;
console.log(regex.test("xyzabc")); // true
console.log(regex.test("xyz")); // false
Przykład: Użycie metody match()
const text = "abc123def456";
const regex = /\d+/g;
console.log(text.match(regex)); // ["123", "456"]
Przykład: Użycie metody replace()
const text = "Hello World";
const regex = /World/;
console.log(text.replace(regex, "Tadeusz")); // "Hello Tadeusz"
Praktyczne przykłady
1. Walidacja adresu e-mail
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test("tadeusz.graczyk@example.com")); // true
console.log(emailRegex.test("niepoprawny@email")); // false
2. Sprawdzenie numeru telefonu
const phoneRegex = /^\d{3}-\d{3}-\d{3}$/;
console.log(phoneRegex.test("123-456-789")); // true
console.log(phoneRegex.test("12-345-6789")); // false
3. Wyszukiwanie daty
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
console.log(dateRegex.test("2023-12-31")); // true
console.log(dateRegex.test("31-12-2023")); // false
4. Ekstrakcja adresów URL
const urlRegex = /https?:\/\/[^\s]+/g;
const text = "Wizyta na stronie https://example.com lub http://test.pl";
console.log(text.match(urlRegex)); // ["https://example.com", "http://test.pl"]
Zaawansowane techniki

Wyrażenia regularne oferują również bardziej zaawansowane funkcje, takie jak:

  • Grupy wychwytujące: Pozwalają na wyodrębnienie części dopasowanego tekstu.
  • Grupy niewychwytujące: Używane do grupowania bez wychwytywania.
  • Asercje: Pozwalają na dopasowanie wzorca tylko w określonych kontekstach.
Przykład: Grupy wychwytujące
const regex = /(\d{2})-(\d{2})-(\d{4})/;
const date = "31-12-2023";
const match = date.match(regex);
console.log(match[1]); // "31"
console.log(match[2]); // "12"
console.log(match[3]); // "2023"
Przykład: Asercje
const regex = /(?<=@)\w+/; // Dopasowuje słowo po znaku @
const email = "tadeusz@example.com";
console.log(email.match(regex)[0]); // "example"
Dobre praktyki

Podczas pracy z wyrażeniami regularnymi warto pamiętać o kilku zasadach:

  • Testuj wyrażenia: Używaj narzędzi takich jak Regex101, aby sprawdzać poprawność swoich wzorców.
  • Unikaj zbyt skomplikowanych wyrażeń: Im prostszy wzorzec, tym łatwiej go zrozumieć i utrzymywać.
  • Dokumentuj: Dodawaj komentarze do skomplikowanych wyrażeń, aby ułatwić ich zrozumienie innym programistom.
  • Optymalizuj: Unikaj nadmiernego użycia kwantyfikatorów, które mogą prowadzić do problemów z wydajnością.
Podsumowanie

Wyrażenia regularne to niezwykle przydatne narzędzie, które może znacznie uprościć pracę z tekstem. Warto poświęcić czas na ich naukę, ponieważ znajomość regexów otwiera wiele możliwości w programowaniu, szczególnie w kontekście walidacji danych, przetwarzania tekstu oraz parsowania informacji.

Dzięki wyrażeniom regularnym możesz precyzyjnie kontrolować, jakie dane są akceptowane przez Twoje aplikacje, co jest kluczowe dla zapewnienia ich poprawności i bezpieczeństwa.