2013-04-16 14 views
12

Potrzebuję wyrażeń regularnych, które analizują arbitralne wyrażenie (jako ciąg znaków), zwracając liczbę grup przechwytywania. Do tej pory mam ...Regex do zliczania grup przechwytywania w regex

arbitrary_regex.toString().match(/\((|[^?].*?)\)/g).length 

Który działa w niektórych przypadkach, gdy założenie, że każda grupa, która zaczyna się od znaku zapytania, nie jest przechwytywanie. Zlicza także puste grupy.

Nie działa dla nawiasów uwzględnionych w klasach znaków, nawiasach ewakuowanych i ewentualnie w innych scenariuszach.

+6

Regex w regex ... [Yo dawg] (http://memearchive.net/memerial.net/5615/yo-dawg-i-herd-you-like-regex.jpg) – Kninnug

Odpowiedz

19

Modyfikowanie regex tak, że będzie on pasował pusty ciąg znaków, a następnie dopasować pusty ciąg i zobaczyć, jak wiele grup powraca:

var num_groups = (new RegExp(regex.toString() + '|')).exec('').length - 1; 

Przykład: http://jsfiddle.net/EEn6G/

+0

Wspaniałe rzeczy - Nigdy bym nie pomyślał o zrobieniu tego w ten sposób! –

+0

+1 Piękny pomysł, Andrew. Dobra robota. :) – zx81

+0

Czy ktoś może wyjaśnić czym jest rura? – Albin

1

Zaakceptowanych odpowiedź jest to, co powinno używać w dowolnym systemie produkcyjnym. Jeśli jednak chcesz go rozwiązać za pomocą wyrażeń regularnych dla zabawy, możesz to zrobić, jak pokazano poniżej. Zakłada, że ​​wyrażenie regularne, które ma mieć poprawną liczbę grup, jest poprawne.

Należy pamiętać, że liczba grup to po prostu liczba niedosłownych ( s w wyrażeniu regularnym. Strategia, którą zamierzamy podjąć, zamiast dopasować wszystkie poprawne (, zamierzamy podzielić na wszystkie niepoprawne rzeczy pomiędzy nimi.

re.toString().split(/(\(\?|\\\[|\[(?:\\\]|.)*?\]|\\\(|[^(])+/g).length - 1 

Możesz zobaczyć, jak to działa na www.debuggex.com.

Powiązane problemy