2016-11-15 13 views
5

Obecnie pracuję nad książką na temat wyrażeń regularnych, a jednym z problemów praktycznych jest napisanie wyrażenia regularnego pasującego do ciągów znaków, które mają taka sama liczba a, jak z i b, jak y. Wcześniej wypowiadałem następujące regularne wyrażenie.Wyrażenie regularne, które pasuje do ciągów znaków z taką samą liczbą liter a, jak z i b jako y

^(?=[^az]*([az][^az]*[az][^az]*)*$)(?=[^by]*([by][^by]*[by][^by]*)*$).*$ 

Problem polega na tym, że nieprawidłowo mecze gdy A i oo są równe i B i Y są równe (tj AZZZ będzie pasować, ale ma więcej, niż się z tych). Czy istnieje sposób modyfikowania mojego wyrażenia regularnego, aby pasował poprawnie lub czy stosuję niewłaściwe podejście?

+2

Jakiego narzędzia/języka używasz do testów? Czy "A" i "Z" są zawsze zamawiane ("AAAZZZ"), czy też można je wymieszać ("AZZAAZA")? To naprawdę nie brzmi jak zadanie, w którym można by użyć regex. –

+0

Korzystam z następujących elementów, aby przetestować: [RegEx101] (https://regex101.com/r/voyrhI/1). A i Z, B i Y mogą być pomieszane według przykładów książek. – WBilger

+1

Czy książka zawiera wyrażenia rekursywne? – shawnt00

Odpowiedz

1

W przypadku niektórych silników wyrażeń regularnych można użyć predefiniowanego subroutines do (niezgrabnie) define context-free grammars, chociaż składnia różni się w zależności od silnika i nie jest ustandaryzowana. Obserwować (wciąż niekompletne, ale dotarcie tam):

(?(DEFINE) 
    (?'all'(?&az)|(?&by)|(?&abzy)|(?&bayz)) 
    (?'az'a(?&all)*z|z(?&all)*a) 
    (?'by'b(?&all)*y|y(?&all)*b) 
    (?'abzy' 
     a(?&all)*b(?&all)*z(?&all)*y| 
     a(?&all)*y(?&all)*z(?&all)*b| 
     z(?&all)*b(?&all)*a(?&all)*y| 
     z(?&all)*y(?&all)*a(?&all)*b 
    ) 
    (?'bayz' 
     b(?&all)*a(?&all)*y(?&all)*z| 
     b(?&all)*z(?&all)*y(?&all)*a| 
     y(?&all)*a(?&all)*b(?&all)*z| 
     y(?&all)*z(?&all)*b(?&all)*a 
    ) 
) 

^(?&all)+$ 

Demo on Regex101

Co to jest określenie zestawu podwzorów i stosuje je rekurencyjnie. Korzystanie z kotwic ^ iw rzeczywistym "wzorze" zapewnia, że ​​cały ciąg pasuje do nich. Prostota sama w sobie.

Chociaż, jeśli faktycznie robisz coś takiego w środowisku produkcyjnym, ktoś może cię zastrzelić, kiedy go znajdzie.

+0

Twoja grupa nazwana 'abzy' zawiera warianty zaczynające się od' b' lub 'y', więc' bzya' nie działa w danym momencie. Również 'abbzyy' nie działa atm. –

+0

@SebastianProske Czy nie możemy zastosować funkcji mapy w każdej linii i wypluć wyjście do innego pliku z numerem linii? Czy nie byłoby to łatwiejsze niż napisanie wyrażenia regularnego, które przeczyłoby Teorii Względności Einsteina? – MYGz

+1

@MohammadYusufGhazi: Przeważnie robię to tylko dla intelektualnego wyzwania, a nie dla prawdziwej próby odpowiedzi. Wiem, że to jest szalone - to sprawia, że ​​jest to zabawne: P –