LW IT Solutions
« Blog Overview /Tworzenie stron internetowych / Wyrażenia regularne: zachłanna kropka, brak kotwic i...
This post in other languages:

Wyrażenia regularne: zachłanna kropka, brak kotwic i zagnieżdżone powtórzenia

Wyrażenia regularne: zachłanna kropka, brak kotwic i zagnieżdżone powtórzenia
Spis treści
  1. Kropka jest zachłanna i kropka nie jest znakiem
  2. Klasa zaprzeczona obejmuje złamanie wiersza
  3. Kotwice mówią gdzie, a nie czy
  4. Zagnieżdżone powtórzenie to problem innego rodzaju
  5. Co sprawdzić, zanim zaufa się wzorcowi
  6. Źródła

Wyrażenie regularne sprawdza się na przypadku, dla którego powstało, trafia i idzie do użytku. Co robi z drugim przypadkiem, to osobne pytanie, a odpowiedź brzmi często: trafia i jego – tyle że nie w to miejsce, o które chodziło.

Trzy poniższe błędy przechodzą każdy przegląd, bo żaden z nich nie zawodzi. Dają coś, to coś wygląda w próbce wiarygodnie, a różnica objawia się jako lekko błędne dane, a nie jako komunikat o błędzie.

Ten sam wiersz HTML dopasowany czterema wzorcami: zachłanna kropka trafia niemal cały wiersz, wersja leniwa i klasa zaprzeczona znajdują po dwa odnośniki, wersja zakotwiczona nie znajduje nic
Cztery wzorce, jeden wiersz. Wyróżniony obszar to trafienie, ciemniejszy w środku to przechwycona grupa.

Kropka jest zachłanna i kropka nie jest znakiem

.* bierze wszystko, co może dostać, i oddaje tylko to, co oddać musi. W wierszu z dwoma odnośnikami href="(.*)" zaczyna przy pierwszym href, biegnie do końca wiersza, a potem cofa się do ostatniego osiągalnego cudzysłowu – wynikiem jest trafienie zawierające oba odnośniki i znaczniki pomiędzy nimi.

Naprawiają to dwie rzeczy. Leniwy kwantyfikator .*? zatrzymuje się przy pierwszym cudzysłowie, który pozwala dopasować resztę wzorca. Klasa zaprzeczona [^"]* nie potrafi w ogóle przekroczyć cudzysłowu, mówi więc to samo bez żadnych nawrotów – i to ta wersja zasługuje na zapisanie, bo wypowiada warunek, zamiast polegać na tym, jak maszyna się cofa.

Klasa zaprzeczona obejmuje złamanie wiersza

Kropka nie trafia złamania wiersza, dopóki nie ustawi się przełącznika s. Zaprzeczona klasa znaków trafia je – [^&] znaczy wszystko, co nie jest ampersandem, a złamanie wiersza ampersandem nie jest.

tekst    utm_source=newsletter
         utm_medium=email

^utm_([a-z_]+)=([^&]+)$      z przełącznikiem m: 2 trafienia
^utm_([a-z_]+)=([^&]+)       bez niego: 1 trafienie przez oba wiersze
^utm_([a-z_]+)=([^&\s]+)     naprawa: białe znaki też wykluczone

To ten błąd, który wygląda na problem z danymi. Wzorzec wyciągający parametry z wielowierszowego wejścia zwraca wartość przypadkiem zawierającą wszystko, co po niej następuje, wartość trafia do pola, a pole wygląda na bardzo długą nazwę kampanii, a nie na usterkę.

Kotwice mówią gdzie, a nie czy

Bez kotwic wzorzec trafia gdziekolwiek w wejściu, co przy wyciąganiu zwykle jest pożądane, a przy sprawdzaniu prawie nigdy. Sprawdzenie, czy pole zawiera same cyfry, przechodzi z [0-9]+ również dla abc123def, bo o resztę wzorca nikt nie zapytał.

Sprawdzanie potrzebuje ^ i $ po obu stronach oraz wiedzy, co te dwa znaczą w używanej odmianie: bez przełącznika wielowierszowego początek i koniec całego wejścia, z nim – każdego wiersza. Które z dwóch jest właściwe, zależy wyłącznie od tego, czy wejście jest jedną wartością, czy ich listą – a to pytanie zasługuje na wyraźną odpowiedź zamiast na ustawienie domyślne, które przyniosła biblioteka.

Zagnieżdżone powtórzenie to problem innego rodzaju

Trzy powyższe błędy dają odpowiedź błędną. Ten nie daje żadnej. Gdy powtarzana grupa zawiera coś, co samo daje się powtarzać – (a+)+, (\s*\w+)*, (.*,)* – istnieje wykładniczo wiele sposobów rozdzielenia wejścia między powtórzenia, a maszyna próbuje ich wszystkich, zanim stwierdzi, że trafienia nie ma.

Wzorzec Wobec niepasującego wejścia długości n
(a+)+$ wykładniczo – trzydzieści znaków to już sekundy
(\s*\w+)*$ ten sam kształt, schowany za dwiema niewinnie wyglądającymi klasami
^(\w+\s?)+$ rozpowszechniony wzorzec do sprawdzania imion i awaria usługi
a+$ liniowo – zewnętrzne powtórzenie było całym problemem

Niebezpieczną własnością jest to, że wzorce te są szybkie przy każdym wejściu, które pasuje. Wybuch następuje tylko przy wejściach niepasujących – wzorzec sprawdzający zachowuje się więc latami nienagannie, potem trafia na jedno wadliwe zgłoszenie i zajmuje proces roboczy, dopóki ktoś go nie ubije.

Reguła przeciw temu jest mechaniczna: żadnego kwantyfikatora bezpośrednio wokół grupy, której zawartość sama jest powtarzana. Gdzie tego nie da się uniknąć, klasa zaprzeczona zwykle wyraża ten sam zamiar – [^,]+, zamiast (.*,) – i zabiera wieloznaczność, którą nawroty przetrząsały.

Co sprawdzić, zanim zaufa się wzorcowi

Trzy wejścia odpowiadają na większość. Przypadek, dla którego wzorzec powstał, dla potwierdzenia, że trafia. Przypadek z dwoma wystąpieniami – tam ujawnia się zachłanność, a przy jednym przykładzie nie ujawni się nigdy. I przypadek, który trafić nie może; tam zdradzają się zarówno kotwice, jak i zagnieżdżone powtórzenie – jedne tym, że trafiają mimo wszystko, drugie tym, że nie kończą pracy.

Trzeci jest tym pomijanym i tym, który łapie oba problemy niewidoczne przy czytaniu wzorca. Zestaw sprawdzeń dla wyrażenia regularnego ma trzy wiersze i jest różnicą między wyrażeniem, które działa, a takim, któremu nikt jeszcze nie zaprzeczył.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

Napisanie komentarza

Adres e-mail nie jest publikowany. Pola obowiązkowe oznaczono gwiazdką.

ALL ARTICLES & CATEGORIES

CCTV

Śledź tę kategorię przez RSS

Cloud & AI

Śledź tę kategorię przez RSS

Data Privacy

Wszystkie artykuły w tej kategorii (12) Śledź tę kategorię przez RSS

Digital Analytics

Wszystkie artykuły w tej kategorii (47) Śledź tę kategorię przez RSS

Digital Marketing

Wszystkie artykuły w tej kategorii (26) Śledź tę kategorię przez RSS

IT & Networks

Wszystkie artykuły w tej kategorii (16) Śledź tę kategorię przez RSS

Raspberry Pi

Śledź tę kategorię przez RSS

Smart Home

Wszystkie artykuły w tej kategorii (17) Śledź tę kategorię przez RSS

Tworzenie stron internetowych

Śledź tę kategorię przez RSS

Wtyczki i triki WordPress

Śledź tę kategorię przez RSS