2012-12-12 12 views
5

Pisanie bardzo prostego parsera skryptu w ramach szkolnego projektu, a gdy nie jest to wymagane, jestem ciekawy, czy można to zrobić tylko za pomocą wyrażenia regularnego.Regex, ignorowanie wzorca, jeśli jest w cudzysłowach

Składnia jest podobna do ASP, gdzie skrypt zaczyna się od <% i kończy się na%>.

Obsługuje tylko jedno polecenie "pr", które jest takie samo jak echo lub Response.Write.

Teraz używam tego wyrażenia regularnego, aby znaleźć bloki skryptu:

(<%\s*([\s\S]*?)\s*%>) 

Ale jeśli mam polecenie tak:

<% pr "%>"; %> 

... To oczywiście tylko mecz:

<% pr "%> 

Czy istnieje sposób używania czystego wyrażenia regularnego do ignorowania znaczników zamykających zawartych w cudzysłowach? Moim głównym zmartwieniem jest to, że może dopasowywać tagi, które są pomiędzy cytatami, ale faktycznie poza nimi, jeśli to ma sens. Na przykład ...

<% pr "hello world"; %> " 

Technicznie znacznik zamykający jest w cudzysłowie, ale to nie jest w środku „otwarte”, a następnie „Zamknij” środki, raczej na odwrót.

Jeśli jest to możliwe w przypadku wyrażenia regularnego, byłoby to całkiem zgrabne, w przeciwnym razie podejrzewam, że gdybym chciał wesprzeć tę funkcjonalność, musiałbym ręcznie dokonać iteracji przychodzącego tekstu i samemu przeanalizować bloki, co nie jest zbyt ważne. zarówno.

Dzięki!

+0

Jeżeli notowania nie są dopasowane, to niemożliwe. Na przykład, dlaczego twój ostatni przykład nie powinien zostać rozszerzony na '" <% pr "hello world";%> "'. Nie są oba '<%' and '%>' wewnątrz lub na zewnątrz cytatów? Czy możesz zapewnić, że w twoim ostatnim przykładzie końcowe znaki "" zostaną dopasowane później w pliku wejściowym? –

Odpowiedz

3

Myślę, że ten powinien odpowiadać twoim potrzebom: <%(".*?"|.*?)*?%> (patrz: Demo).

Objaśnienie:

Podczas .* mecze jak najdłużej, .*? mecze jak najmniejszym możliwym.

Na przykład (z wykorzystaniem pseudo-kod),

"#foo# #bar#".matches(/#(.*)#/).group(1) // will return ["foo# #bar"] 

podczas

"#foo# #bar#".matches(/#(.*?)#/).group(1) // will return ["foo", "bar"] 
+1

To działa całkiem dobrze! Wmasowałem go trochę, aby dołączyć nowe znaki linii i dodać grupy przechwytujące, których potrzebowałem i wydaje się, że działa świetnie. – ARW

Powiązane problemy