[bcn-pm] Hola

Xavier Noria fxn at hashref.com
Tue Jul 20 04:35:02 CDT 2004


On Jul 20, 2004, at 11:00, Ktala wrote:

> Estic intentant tractar els mètodes del C++ de Micro$oft que tenen com 
> a  format "STDMETHODIMP nom mètode(parametres) {algo}" amb la regex 
> "STDMETHODIMP.*\\n*\\{(.*\\n*)*\\}" però aquesta malparida només 
> m'agafa el primer de cada .cpp perque engloba els altres dins del 
> primer. He pensat de posar que el cos del mètode no contingui la 
> paraula "STDMETHODIMP", però no me'n surto.

El primer problema que estas trobant es que el quantificador * se'n va 
tan a la dreta com pot. Per exemple, donat

     STDMETHODIMP { foo }
     STDMETHODIMP { bar }

l'engine fa matching amb el primer "STDMETHODIMP", llavors fa matching 
amb el primer "{". Be, el que voliem. Ara, pero, el grup (.*\\n*)* fa 
que avanci fins al final de la cadena, es faci backtrack un cop, i es 
matchambri l'ultim "}", el de la dreta de "bar". Total que $& es _tot 
el codi_, ho veus que va aixi?

Altre problema es que si vols fer matching amb el contingut del block 
entre claus (.*\\n*)* no serveix. Aixo es aixi perque a $1 
s'enmagatzema nomes l'ultim dels grups que han fet matching, i en 
aquest cas el backtracking fa que no sigui el que et penses (imprimeix 
$1). En aquesta mena de matchings normalment hom vol quantificar per 
una banda i capturar per sobre:

     ((.*\\n*)*)

Altres problemes son l'aparicio de claus en cadenes, comentaris, i 
demes punyetes que fan que el parsing amb expressions regulars sigui 
practicament impossible de fer-se robust.

Solucions practiques son tirar de Text::Balanced (extract_bracketed), o 
mirar la gramatica basada en regexps que fa anar Inline::CPP 
(http://search.cpan.org/src/NEILW/Inline-CPP-0.25/grammar/grammar.pm), 
per exemple.

-- fxn

PD: Com es que tens la regexp en una cadena? Si no la poses directament 
a m// i companyia es millor fer anar el constructor qr// que admet la 
sintaxi normal.





More information about the Barcelona-pm mailing list