2016-03-20 24 views
5

Zgodnie z PHP manual modyfikator wyrażeń regularnych PCRE umożliwia obsługę standardu UTF-8 zarówno dla wzorca, jak i tematu.preg_split vs mb_split

Biorąc to pod uwagę, czy istnieje jakaś różnica między używaniem wyrażeń PCRE z modyfikatorem u a odpowiadającymi im funkcjami wielobajtowych ciągów znaków mb_*? (. Zakładając, że wszystkie łańcuchy są UTF-8)


Jako przykład, rozważmy preg_split vs mb_split: zarówno

preg_split('/' . $pattern . '/u', $string); 

i

mb_split($pattern, $string); 

wydaje powrotu identyczne wyniki. Który z nich powinien być preferowany? Czy to ma znaczenie?

+1

Powiedziałbym, że to prawie to samo, co porównywanie 'preg_match' i' strpos' dla statycznego wyszukiwania ciągów. –

+1

Dlaczego? 'strpos' nie obsługuje wyrażeń regularnych, czy też się mylę? – emkey08

+1

"** dla statycznego szukania ciągów **" - gdy ciąg jest stały, nie regex ... –

Odpowiedz

5

Główną różnicą jest to, że funkcje preg_ użyć pcre library, gdy funkcje mb_ereg_ (łącznie mb_split) używać oniguruma library (stosowany w Ruby przed wersja 2.0).

Głównym powodem jest to, że oniguruma może obsługiwać wiele kodowań (ASCII, UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE, EUC-JP, EUC-TW, EUC-KR , EUC-CN, Shift_JIS, Big5, GB18030, KOI8-R, CP1251, ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5, ISO-8859 -6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15 , ISO-8859-16) gdy komputer nie może.

Należy pamiętać, że wiele kodowań dostępnych dla mb_ funkcji, takich jak mb_detect_encoding nie są na tej liście (UTF-7, ArmSCII-8, CP866 na przykład) ograniczenie trafność mb_ereg_ funkcji. (Ponieważ musisz przekonwertować ciąg na obsługiwane kodowanie przed rozpoczęciem pracy nad nim, i przekonwertować je później).

Dwa silniki regex mają mniej więcej te same funkcje, niemniej jednak można zauważyć pewne różnice (nie wyczerpująca, jak to jest):

Oniguruma nie obsługuje:

  • jeden list Unicode klas postaci skrótowym być napisane bez nawiasów.
    Przykład: \pN jest postrzegana jako pN, trzeba napisać: \p{N}
  • klas znaków Unicode: Xan, XPS, XSP, Xwd
  • nie uciekł nawiasów kwadratowych w klasy postaci: Oniguruma zobaczyć [][] jak dwa puste charakterem klasy, kiedy pcre zobaczyć klasę postaci, która zawiera ] i [
  • funkcja \K
  • \R alias dla nowej linii sekwencje
  • nazwanych grup, które używają składni Pythona (?P<name>...). Dozwolone jest tylko (?<name>...) lub (?'name'...).
  • odwołania do grupy z czymś innym niż składnia Oniguruma: \g<name> (Składnia Perl (?&name) i (?1) lub (?R) są niedozwolone).
  • Backtracking czasowniki kontroli

PCRE nie wspiera:

  • zduplikowane grupy nazwane (domyślnie). Aby włączyć tę funkcję, musisz użyć modyfikatora (?J).
  • numerowane referencje zwrotne ze składnią \k<...>. Możesz napisać \k<name>, ale nie \k<1> ani \k<-1>.
  • Odsyłacze do określonego poziomu zagnieżdżenia. Oniguruma może to zrobić, używając \k<name+n>, gdzie n jest poziomem gniazda.


Aby dopasować nowych linii z kropką Oniguruma stosuje się modyfikator m przy PCRE stosuje się modyfikator s. W funkcjach mb_ereg_, kropka dopasowuje domyślnie znaki nowej linii. (Tak więc modyfikator m jest włączony domyślnie).

PCRE używa modyfikatora s do dopasowania znaku nowej kropki. Modyfikator zachowuje się inaczej w PCRE, zmienia znaczenie kotwic ^ i $ z "startu" i "końca" ciągu na "początek" i "koniec" linii.

W przypadku Oniguruma znaczenie tych kotew nie ulega zmianie, zawsze pasują do początku i końca linii. Aby dopasować limit ciągu, używa on także \A i \z dostępnego również w PCRE.

Zauważ, że Oniguruma został rozwidlony, aby nadać Onigmo (używane w obecnych wersjach Ruby), który implementuje więcej funkcji Perl i elementów składniowych, i jest bardziej podobny do PCRE.

2

Dopóki pracujesz ściśle z UTF-8, będziesz w porządku z każdym z nich. Jeśli używasz innego charset, zaleca się użycie mb_split(), ponieważ modyfikator u z PCRE nie pozwala na określenie charset, traktując łańcuchy jako UTF-8.

Jeśli chodzi o skalowanie i długoterminową żywotność, odradzam korzystanie z mb_split() od początku, aby zapewnić ochronę w przypadku użycia czegoś innego niż UTF-8 na trasie.

+0

Masz na myśli 'mb_split' zamiast' preg_split', czyż nie? Możesz ustawić kodowanie za pomocą 'mb_regex_encoding', a następnie dla funkcji' mb_ * '. – emkey08

+0

Poprawnie; literówka.Naprawiony; przepraszam i dziękuję. –