Per affrontare parentesi nidificate, è possibile utilizzare:
txt = "a,s(d,f(4,5)),g,h"
pattern = Regexp.new('((?:[^,(]+|(\((?>[^()]+|\g<-1>)*\)))+)')
puts txt.scan(pattern).map &:first
dettagli del modello:
( # first capturing group
(?: # open a non capturing group
[^,(]+ # all characters except , and (
| # or
( # open the second capturing group
\( # (
(?> # open an atomic group
[^()]+ # all characters except parenthesis
| # OR
\g<-1> # the last capturing group (you can also write \g<2>)
)* # close the atomic group
\) #)
) # close the second capturing group
)+ # close the non-capturing group and repeat it
) # close the first capturing group
Il secondo gruppo di cattura descrivono la parentesi annidata che può contenere caratteri che non sono parentesi o la cattura gr stesso. È un modello ricorsivo.
All'interno del modello, è possibile fare riferimento ad un gruppo di cattura con il suo numero (\g<2>
per il secondo gruppo di cattura), o con la sua posizione relativa (\g<-1>
la prima a sinistra dalla posizione corrente nel pattern) (o con il suo nome se si utilizzano gruppi di acquisizione denominati)
Avviso: è possibile consentire una singola parentesi se si aggiunge |[()]
prima della fine del gruppo non di acquisizione. Quindi a,b(,c
ti darà ['a', 'b(', 'c']
fonte
2013-08-25 00:45:35
'txt.scan (pattern) .map &: first' ha risolto il problema. @casimir davvero non posso raddoppiare-votare la tua risposta, grazie! – Naveed
puoi spiegare questa espressione regolare? è fuori di testa :) – Naveed
Ero curioso di -1 in regexp. puoi spiegare anche questa parte? <-1> ' – Naveed