8
votes

Comment supprimer des commentaires suivis via Regexp?

Pour les lecteurs non-MATLAB-Savvy: Je ne sais pas quelle famille ils appartiennent, mais les regextes Matlab sont décrits ici en détail en détail. Le caractère de commentaire de Matlab est % (pourcentage) et son délimiteur de chaîne est ' (Apostrophe). Un délimiteur de chaîne à l'intérieur d'une chaîne est écrit sous forme d'une double-Apostophe ( 'C'est ainsi que vous écrivez "c'est" "dans une chaîne" ). Pour compliquer davantage les choses, les opérateurs de transposition de la matrice sont aussi Apostrophes ( a ' (hermitien) ou a.' (régulier)).

Maintenant, pour des raisons sombres (que je vais pas élaborer sur :), j'essaie d'interpréter le code Matlab dans la langue de Matlab.

Actuellement, j'essaie de supprimer tous les commentaires suivants dans un tableau de cellules de chaînes, chacun contenant une ligne de code MATLAB. Au premier abord, cela peut sembler simple: xxx

mais bien sûr, quelque chose comme cela pourrait venir: xxx

Évidemment, nous devons exclure tous les caractères de commentaire qui résident à l'intérieur des chaînes du match, tout en tenant compte que d'une seule apostrophe (ou d'un dot-aposrotphe) directement à la suite d'une déclaration est un opérateur , pas un Délimiteur de chaîne.

en fonction de l'hypothèse selon laquelle la quantité de caractères d'ouverture / fermeture de chaîne avant le caractère de commentaire doit être même (que je sais est incomplète En raison de l'opérateur de transposition de la matrice), j'ai évoqué la regex dynamique suivante pour gérer ce type de cas: xxx

Cependant, xxx < / pré>

donc je suis presque là-bas, mais pas encore encore :)

Malheureusement, j'ai épuisé la quantité de temps que je peux passer à penser à cela et à avoir besoin continuer avec d'autres choses, alors peut-être que quelqu'un d'autre qui a plus de temps est suffisamment amical pour réfléchir à ces questions:

  1. Les personnages de commentaires sont-ils à l'intérieur des chaînes la seulement exception que j'ai besoin de rechercher?
  2. Quel est le moyen correct et / ou plus efficace de faire cela?

20 commentaires

Je ne connais pas Matlab mais que diriez-vous d'utiliser un quantifier non gourmand: %. *? $


@ M42: Eh bien, cela semble résoudre le problème, au moins pour mon petit sous-ensemble de tests ... Pouvez-vous poster comme une réponse?


@ M42: Pas d'attente, je n'ai pas assez d'air assez proche - c'est pas corrige le problème ... En fait, ça ne fait plus rien :)


Eh bien, si les instructions se terminent par Semicolon, cela fonctionnera peut-être: substituer ; \ s *%. *? $ par ;


@ M42: Malheureusement, toutes les lignes finissent pas dans le point-virgule (par exemple, si (condition)% commentaire de suivi est un motif couramment de l'occultation)


Dommage, alors je suppose que le meilleur moyen est un analyseur.


Allez-vous garder des directives comme % # ok et % # codegen ou est ok pour les supprimer aussi bien?


@Mohsennosratinia: Je ne suis intéressé que par les déclarations, il est donc correct de les supprimer


D'une manière ou d'une autre, je pense qu'il serait plus facile d'écrire un analyseur de machine à états fini que d'écrire son regex correspondant.


@Jandvorak: Vous avez probablement raison, je suis juste en train d'explorer la possibilité que j'ai négligé quelque chose d'évident (ou pas - si évident - et facile à manquer)


@RODYOLDENHUIS Si MATLAB prend en charge le lookeDewind, vous pouvez convertir cette FSM en une regex et l'utiliser comme étant la photo. L'état de départ et de fin de la lunette serait le contexte «normal». La partie après que la lunette soit facile.


@Jandvorak: Afaik, Matlab a en effet un soutien pour cela. Il est alors "juste" une question de recherche de la regex qui trouve: "La sous-chaîne la plus longue où tout avant le caractère de commentaire contient un nombre pair de caractères joints de chaîne, où les caractères joints de chaîne sont comptés seulement s'ils ne sont pas directement attachés à un caractère non-espace qui n'est pas dans une ficelle elle-même. "... sonne comme amusant :)


Donc, chaque apostrophe qui n'est pas directement après a , a. ou commenté est un délimiteur de chaîne?


Comment Matlab traite-t-il les nouvelles lignes à l'intérieur des chaînes?


@Jandvorak: En effet (bien sûr, votre " A " est une instruction valide et " '" et "code>" ' est la transposition les opérateurs). Les nouvelles lignes dans les chaînes ne sont pas prises en charge directement (vous construiriez une gamme 2D de chaînes pour accomplir cela, ou utiliser char (10) dans un tableau 1D, ou Utilisez \ n dans fprintf () et amis.)


Umm ... Ensuite, j'ai besoin de la grammaire pour une déclaration valide, ou au moins une grammaire désambiguant entre le contexte valide pour une transposition matricielle et le contexte valide pour un littéral à chaîne. Je ne connais pas la syntaxe de Matlab, mais je comprends la théorie de l'analyse d'une grammaire spécifique.


@Jandvorak: Les détails sont bien sûr un peu trop longs pour un commentaire, mais je pense que vous trouverez Cette question utile. Pour les transpositions: chaque apostrophe précédé d'un caractère anti-blancheur et de caractère non apostrophe, est un opérateur de transposition matricielle, à condition qu'il ne soit pas à l'intérieur d'une chaîne délimitée de l'Apostrophe.


@Jandvorak: Apostophe non précédé par une chaîne elle-même et directement précédé par \ s , \ (, \ [ ou \ { est un caractère d'ouverture de chaîne. L'apostrphe étrange suivante, lorsqu'il ne comptant pas double Apostrophes, est un terminateur à chaîne (comme vous pouvez le remarquer, je suis avoir du mal à la définir :))


Par "non précédé d'une chaîne elle-même", voulez-vous dire que dans 'hello' '' , le dernier ' désigne une transposition de matrice? Qu'en est-il de 'hello' op 'ov' world '?


@Jandvorak: 'Hello' '' n'est pas valide (directement précédé par Apostrophe), tandis que 'Hello'. ' est en effet une transposition valide de la matrice de caractères. Quelque chose comme 'hello'. ^ 'World' est une instruction valide (. ^ est l'exponentiation de l'élément-sage et une matrice de caractères est (comme c) seulement un tableau de Nombres)


5 Réponses :


1
votes

Que diriez-vous de vous assurer que toutes les apostrophes avant que le commentaire ne vienne par paires comme ceci: xxx


1 commentaires

a l'air mieux ... mais malheureusement échoue sur quelque chose comme str = 'a = a.' ';% de commentaire suivant'



2
votes

Je préfère abuser checkcode (le remplacement pour l'ancien href = "http://www.mathworks.se/help/matlab/ref/mlint.html" rel = "nofollow"> mlint ) pour analyser. Voici une suggestion xxx

pour chaque ligne, elle vérifie si nous introduisons une erreur en coupant la ligne de la ligne du dernier % à la fin de la ligne.

pour votre exemple, il renvoie: xxx

Il ne supprime pas la directive de suppression, % # ok , donc vous obtenez : xxx

ce qui est probablement une bonne chose.


3 commentaires

+1: Vous, mon bon monsieur, devient vite mon nouveau héros! Vous êtes si plein de tesselles sales: p Quoi qu'il en soit, bien que je conviens que c'est probablement la voie la plus robuste et la plus «meilleure», elle se sent terriblement verbeuse ... Plus, cela crée une dépendance de la version: je suis sur R2010a , donc je devrai utiliser mlint au lieu de Codecheck (qui, idéalement, je devrais vérifier). Donc, je laisserai la question ouverte pendant un moment plus longtemps, voir si une refuge à une seule linger est vraiment pas possible.


Thassk pour les gentils mots! En effet pas aussi succinct qu'un regexprep . Je suis également curieux d'une solution avec regex, mais je vois de nombreux cas spéciaux pour traiter principalement du fait que ' peut être utilisé à la fois pour la chaîne et la transposition conjuguée.


Oui, cette apostrophe est un méchant n'est-ce pas?



4
votes

Ceci correspond à la vérification de la conjugué Transpose en vérifiant quels caractères sont autorisés avant un

  1. Numéros 2 '
  2. lettres a '
  3. dot a. '
  4. Parenthèses gauche, cornée et support a (1) ', a {1}' et [1 2 3] '

    Ce sont les seuls cas que je peux penser maintenant. xxx

    sur votre exemple, nous renvoyons xxx


9 commentaires

+1 (encore): Commencer à bien paraître ... Des tests supplémentaires sont nécessaires.


@ M42 Votre commentaire est superflu puisqu'il utilise [^ ''] * .


@ M42 Ce n'est pas le cas. Vous voyez [^ ''] mais ce n'est pas la chaîne réelle. Matlab le convertira en [^ '] . Si vous souhaitez avoir une apostrophe dans une chaîne MATLAB, vous devez le répéter. Si vous exécutez DISP ('' c'est une chaîne ') , vous obtenez c'est une chaîne .


@Mohsennosratinia: Ok, désolé, mon mauvais. Je ne connais pas la syntaxe Matlab.


Regardez ma réponse :) Pouvez-vous voir si vous pouvez trouver une construction sur laquelle elle échoue?


Je vais toujours accepter votre réponse, car votre solution a également résisté à mes tests jusqu'à présent, et vos efforts de hacky sont grandement appréciés :)


Hmm ... quelque chose qui ne m'a pas encore eu pour moi: Commentaires multi-lignes (% {...%} ) devrait idéalement aussi être supprimé (complètement). ..


Merci d'avoir choisi celui-ci. Je pense que si vous souhaitez gérer des multilignes, vous devez modifier votre structure de données. La matrice de cellules causera plus de problèmes. Vous devez le ramener à une longue chaîne multi-lignes.


Eh bien, je traiterai des commentaires multilignes séparément (assez facile, bien que pas dans un afaik one-liner) ... Je pense qu'il est assez impossible de dépouiller aussi ceux dans une doublure :)



4
votes

Regarde ce que j'ai trouvé! :)

Le commentaire Boîte à outils de stripping , par Peter J. Acklam.

pour le code M, il contient la regex suivante: xxx

qui devient xxx

et doit être utilisé comme xxx

jusqu'à présent, il est resté à tous mes tests, alors je pense que cela devrait résoudre mon problème assez joliment :)


0 commentaires

5
votes

Comment vous sentez-vous de l'utilisation de fonctionnalités non documentées? Si vous ne vous objectez pas, vous pouvez utiliser la fonction mTRee pour analyser le code et déposer les commentaires. Pas de regexples impliqués et Nous savons tous que nous ne devrions pas essayer d'analyser les grammaires sans contexte en utilisant des expressions régulières.

Cette fonction est un analyseur complet de code MATLAB écrit dans le code M pur. Pour autant que je sache, c'est une implémentation expérimentale, mais elle est déjà utilisée par Mathworks dans quelques endroits (c'est la même fonction utilisée par MATLAB CODY et Concours pour mesurer la longueur du code), et peut être utilisé pour Autres choses utiles utiles.

Si l'entrée est une cellier de chaînes, nous faisons: xxx

Si vous avez déjà un fichier M stocké sur disque, vous pouvez dépouiller la Commentaires Tout simplement comme: xxx

Si vous souhaitez voir les commentaires de retour, ajoutez: mtree (.., '-Comments')


1 commentaires

Pour être exact mTtree appelle une fonction intégrée mtreemex , donc ce n'est pas une fonction pure m de code M