Zwiń i przechwyć powtarzający się wzór w pojedynczym wyrażeniu regex
Wciąż wpadam na sytuacje, w których muszę przechwycić pewną liczbę żetonów ze sznurka i po niezliczonych próbach nie mogłem znaleźć sposobu na uproszczenie tego procesu.
Powiedzmy, że tekst jest:
start: test-test-lorem-ipsum-sir-doloret-etc-etc-something: end
Ten przykład zawiera 8 elementów, ale powiedzmy, że może mieć od 3 do 10 elementów.
Idealnie chciałbym coś takiego:start:(?:(\w+)-?){3,10}:end
ładne i czyste ALE to tylko ostatni mecz.Spójrz tutaj
Zazwyczaj używam czegoś takiego w prostych sytuacjach:
start:(\w+)-(\w+)-(\w+)-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?:end
3 grupy obowiązkowe i kolejne 7 opcjonalne z powodu limitu maks. 10, ale to nie wygląda „miło” i byłoby trudno napisać i śledzić, czy maksymalny limit wynosił 100, a mecze były bardziej złożone.próbny
A najlepsze, co mogłem zrobić do tej pory:
start:(\w+)-((?1))-((?1))-?((?1))?-?((?1))?-?((?1))?-?((?1))?-?((?1))?:end
krótszy, zwłaszcza jeśli mecze są złożone, ale wciąż długie.próbny
Każdemu udało się sprawić, by działało jako jedno rozwiązanie oparte wyłącznie na wyrażeniach regularnychbez programowania?
Najbardziej interesuje mnie, jak można to zrobić w PCRE, ale inne smaki też będą w porządku.
Aktualizacja:Celem jest walidacja meczu i przechwycenie pojedynczych tokenów w środkumatch 0
tylko przez RegEx, bez ograniczeń systemu operacyjnego / oprogramowania / języka programowania
Dzięki pomocy @ nhahtdh dotarłem do RegExp poniżej, używając\G
:
(?:start:(?=(?:[\w]+(?:-|(?=:end))){3,10}:end)|(?!^)\G-)([\w]+)
próbny nawet krótszy, ale można go opisać bez powtarzającego się kodu
Interesuje mnie także smak ECMA i nie obsługuje\G
zastanawiam się, czy jest inny sposób, zwłaszcza bez użycia/g
modyfikator.