2010-11-11 15 views
2

J'ai besoin d'analyser certains fichiers texte à la recherche de classes php. Ainsi, par exemple, si j'ai un fichier texte avec cette source:Regex et PHP pour obtenir le contenu de la classe Java/PHP à partir d'un fichier source

... texte ...

... un autre texte ...

class Foo {

fonction barre ($ param) { ... faire des choses ...}

}

... un autre texte ...

Bar class {{

Foo() fonction

... faire quelque chose .... }

}

... une autre ...

Dans ce cas, mon expression régulière doit correspondre aux deux classes et le contenu des cours, pour revenir ce résultat:

premier résultat:

class Foo {

fonction bar ($ param) { ... faire des choses ...}

}

deuxième résultat :

Bar class {

fonction Foo() {... faire quelque chose .... }

}

J'ai essayé beaucoup de fois mais malchanceux. Mon dernier test était

/^ [\ n \ r \ t] (: résumé | classe | interface) {1} (.) [^ (?: Classe | interface)] * $/im

mais il ne correspond qu'à

class Foo {

et

Bar class {

sans le contenu de la classe.

Merci pour votre aide :)

+1

Demandez-vous comment faire correspondre le contenu d'un peut-être imbriqué '{..}' structure de bloc? – tchrist

+0

Bonjour et bienvenue dans Stack Overflow. Pour écrire du code, n'utilisez pas '>' mais collez plutôt le code, sélectionnez-le et appuyez sur Ctrl-K. Ceci est vraiment mieux. –

Répondre

2

Cela ne peut être fait avec des expressions régulières « classiques » parce que vous auriez besoin de pouvoir gérer de façon arbitraire entre parenthèses imbriquées, et les structures comme celles-ci sont par définition irréguliers. Certains langages de programmation (.NET, PCRE, Perl 5.6 et plus) ont augmenté les expressions régulières pour prendre en charge la correspondance récursive, mais la plupart des implémentations ne peuvent pas encore gérer la récursivité. Je parierais également que même si le moteur regex de votre langue préférée peut gérer la récursivité, ce n'est généralement pas la meilleure façon d'y aller. La plupart du temps, vous voulez plutôt un analyseur pour cela. Cela dit, même sans expressions régulières récursives, vous pourriez avoir une chance si votre code est formaté de manière cohérente (colonne de départ de la définition de classe == colonne de la fermeture }, pas de mélange d'onglets et d'espaces, et chaque sous la structure de niveau est en retrait).

Ensuite, vous pouvez essayer

/^([\t ]*)(?:abstract|class|interface).*?^\1\}/sim 

Mais c'est sûr d'échouer horriblement si votre code est pas exactement formaté en fonction de ces règles.

Explication:

^        # start of line 
([\t\ ]*)      # match and remember whitespace 
(?:abstract|class|interface) # match keyword 
.*?       # match as few characters as possible 
^\1       # until the next line that starts with the same amount of whitespace 
\}       # followed by a } 
+0

Tim Tim Tim, s'il vous plait, arrêtez de dire "ça ne peut pas être fait avec des regex". C'est [pas vrai] (http://stackoverflow.com/questions/4031112/regular-expression-matching/4034386#4034386). – tchrist

+0

@tchrist: OK, j'ai clarifié ma réponse. Un peu :). Je ne pense toujours pas que c'est une bonne chose d'utiliser la récursivité dans les expressions régulières même si certains dialectes modernes le peuvent. Les regex sont déjà assez dures ... –

+0

Not perl6. Perl5 l'a eu depuis au moins 5,6 à l'arrière du dernier millénaire. La chose récursion de tampon plus frais est cependant de 5.10 et environ trois ans. – tchrist