[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: regexp multiline che conta le coppie di parentesi



On 11/01/2012 10:29, Federico Bruni wrote:

Mi spiego meglio: voglio creare una regexp capace di individuare un
blocco di questo tipo:

#(define (helper ls1 ls2 ls3)
"Constructs an alist with the elements of ls1 and ls2"
(set! ls3 (assq-set! ls3 (car ls1) (car ls2)))
(if (null? (cdr ls1))
ls3
(helper (cdr ls1) (cdr ls2) ls3)))

\check highlight


Quello compreso tra #( e ls3)))

puoi usare bgrep[1] che è il grep multilinea che permette di identificare blocchi di dati tramite espressioni regolari. Solo che devi aspettare che rilascino la prima versione... per ora c'è lo studio e non so se ci sia un prototipo o l'accesso ad un repository per i sorgenti.

C'è un modo per contare le parentesi aperte e completare il "match" solo
quando trova un egual numero di parentesi chiuse?

puoi scriverti un piccolo script bash (o Perl o altro)

Per esempio questo che dato un carattere che di sicuro non trovi nei tuoi file $SpecialChar ti estrae tutte le occorrenze presenti nel file $NomeFile (puoi usare anche un parametro di input) che iniziano con "#(" e che terminano con ")" dove l'ultima parentesi chiusa chiude l'iniziale aperta. Ti riporta ogni occorrenza su una sola riga (elimina gli a capo, volendo si può modificare per mantenerli) e separa le occorrenze trovate con una riga vuota.

----8<-------8<-------8<-------8<-------8<-------8<-------8<-------8<---
#!/bin/bash

NomeFile="a.txt"
SpecialChar='§' # usare un carattere che non presente di sicuro nel file

OldIFS=$IFS
IFS="$SpecialChar
"
TrovatoPound=0
NumParentesi=0

for i in $(sed "s/\(.\)/\1$SpecialChar/g" $NomeFile); do

 if [[ "$i" = "(" ]] && [[ $NumParentesi -gt 0 ]]; then
  NumParentesi=$(($NumParentesi+1))
 fi

 if [[ $TrovatoPound -eq 1 ]] && [[ "$i" = "(" ]]; then
   NumParentesi=$(($NumParentesi+1))
   echo -n "#"
  else
   TrovatoPound=0
 fi

 if [[ $NumParentesi -gt 0 ]]; then
  echo -n "$i"
 fi

 if [[ "$i" = ")" ]] && [[ $NumParentesi -gt 0 ]]; then
  NumParentesi=$(($NumParentesi-1))
  if [[ $NumParentesi -eq 0 ]]; then
   TrovatoPound=0
   NumParentesi=0
   echo -e "\n"
  fi
 fi

 if [[ "$i" = "#" ]] && [[ $NumParentesi -eq 0 ]]; then
  TrovatoPound=1
 fi

done


IFS=$OldIFS
----8<-------8<-------8<-------8<-------8<-------8<-------8<-------8<---


se ti serve qualcosa che operi su file di certe dimensioni, allora è meglio usare un linguaggio un po' più veloce... i più veloci sono C e C++

Ciao
Davide

[1]
http://www.cs.dartmouth.edu/reports/abstracts/TR2011-705/


--
Dizionari: http://linguistico.sourceforge.net/wiki
Sistema operativo: http://www.it.debian.org
GNU/Linux User: 302090: http://counter.li.org
Non autorizzo la memorizzazione del mio indirizzo su outlook


Reply to: