Wyjścia nie są poprawnie opisane, to wszystko.
Po pierwsze, co powinno być powinno być? Jeśli powtórzysz grupę, każda nowa instancja zastąpi ostatnie przechwycenie. Jeśli grupa nie jest w ogóle używana, zwróci pusty ciąg znaków lub coś w rodzaju JS (zależnie od smaku). Istnieje dobry artykuł na temat regular-expressions.info w tej sprawie.
Teraz, jak możemy osiągnąć twoje wyniki? Zacznijmy od JavaScript.
Wszystkie przykłady oznaczone jako JS
(inne niż globalne) pasują do powyższego opisu. Pasują do żądanej liczby znaków w 0
i przechwytują ostatni znak w 1
. Możemy to zignorować.
Co jest z tymi globalnymi? Tutaj wynik został nieprawidłowo zinterpretowany. Kiedy używasz globalnej flagi z funkcją String.match()
, nie dostajesz już tablicy wszystkich przechwytujących - ale tylko tablicę wszystkich dopasowań (grupa 0
dla każdego dopasowania). Stąd w przypadku +
, *
i {5}
, gdzie jest tylko jeden mecz, otrzymujesz tylko jeden wynik. Przy {4}
jest wystarczająco dużo miejsca na dwa dopasowania w ciągu docelowym, więc wynikowa tablica zawiera dwa elementy. Aby uzyskać wszystkie przechwyty z flagą globalną, musisz napisać pętlę i użyć zamiast niej wartości RegExp.exec()
(co daje jeden dopasowany obraz na raz, ale wszystkie jego przechwycenia).
A co z PHP? Wygląda na to, że używa on preg_match_all
, która jest globalna i dlatego użycie g
nie przyniosło żadnego efektu. Model +
daje oczekiwany rezultat. Tak samo jest z {5}
.
Co z pozostałymi dwoma? Tutaj wynik został zinterpretowany w niewłaściwy sposób. Domyślnie preg_match_all
podaje tablicę dwuwymiarową, gdzie pierwszy indeks odpowiada grupie, a drugi odpowiada dopasowaniu. W twoim wyjściu jest interpretowany odwrotnie. W związku z tym, gdy występuje wiele dopasowań, pierwsza para 0
i jest zgodna z dwoma znalezionymi dopasowaniami. Druga para to te, które przechwyciłeś w tych dwóch meczach.
Tak więc dla *
najpierw otrzymuje się pełny ciąg jako dopasowanie, a ostatni znak jako przechwytywanie (dwie rzeczy oznaczone jako 0
), co jest poprawne. A ponieważ od *
dopuszcza dopasowania o zerowej szerokości, otrzymasz inny (pusty) mecz na końcu ciągu wraz z pustym przechwytywaniem.Nie jestem pewien, dlaczego odpowiedni przykład JS'
nie zawiera dodatkowego pustego łańcucha, ponieważ String.match
zrobiłby to samo.
I {4}
, po prostu dostać dwa mecze (Trol
i olo!
) jak w przypadku JavaScript z przechwyconych l
i !
, odpowiednio, co jest znowu perfekcyjnie.
Co to są 'JS' i' JS''? Co za różnica? –
Uważam, że ta strona nie podaje właściwych grup. Zamiast tego użyj http://www.regexplanet.com/. –