This post comes from the first version of this blog.
Please send me an email if anything needs an update. Thanks!

Szukałem ostatnio szybkiego sposobu na podzielenie stringa według jednoznakowego separatora, aczkolwiek w taki sposób, by omijał jego “escape’owaną” formę. W ten sposób mógłbym np. parsować pewne dane tekstowe równocześnie umożliwiając wykorzystanie separatora w samym tekście. Zadanie teoretycznie nie wydawało się trudne, aczkolwiek faktyczne rozwiązanie okazało się co najmniej “nietrywialne”. W dzisiejszym bardzo krótkim i treściwym wpisie chciałbym podzielić się z Wami znalezionym przeze mnie rozwiązaniem.

Fotografia: Maddingue, CC-BY-SA.

PHP: Dzielenie stringa według separatora z wyłączeniem znaku ucieczki.

Rozwiązań oczywiście jest kilka: Nie muszę mówić, że ostatnia opcja jest najbardziej atrakcyjna, także zdecydowałem, że pójdę tą właśnie drogą. Biblioteka standardowa PHP udostępnia bardzo fajną funkcję preg_split(), także mamy już w rękach narzędzie, teraz trzeba je tylko uzbroić w odpowiednie wyrażenie regularne. W dokumentacji do wspomnianej funkcji trzeci komentarz opisuje bardzo ciekawy sposób na osiągnięcie tego celu:
If you want to split by a char, but want to ignore that char in case it is escaped, use a lookbehind assertion.

In this example a string will be split by “:” but “:” will be ignored:

Results into:

Array ( [0] => a [1] => b [2] => c:d )

A więc musimy użyć wyrażenia regularnego:

#(?<!\\\)\X#

gdzie X oznacza znak, według którego chcemy podzielić nasz string. Wyjaśnienie mechanizmu działania tego wyrażenia będzie nieco karkołomną sprawą, ponieważ zagadnienie tzw. “lookbehind” i towarzyszącemu mu “lookahead” jest w pewnym sensie “czarną magią” implementacji regexpów. Jest to jedna z tych rzeczy, które potrafię zastosować, jeśli będą potrzebne, aczkolwiek nie wnikam zbyt głęboko w siedzące niżej mechanizmy. Dlatego też nie chcę publikować potencjalnie błędnej interpretacji, pomimo dobrych chęci. Jeśli czujecie się na siłach, zapraszam do wyjaśnień w komentarzach. Polecam lekturę w tym temacie tutaj.

Przy okazji - nie wiem, jak to jest, że parę dni temu opublikowałem harmonogram, a już mam pierwsze spóźnienie. Nie brzmi to zbyt przyjemnie, ale co poradzić - sprawy blogowe kompletnie wypadły mi dzisiaj z głowy. Cóż, miejmy nadzieję, że nie powtórzy się to w przyszłości [i tak się pewnie powtórzy, ale od czego jest wiara we własne siły?]. Dziękuję za lekturę i do zobaczenia w kolejnym wpisie w piątek. ;]