10
votes

Expression régulière pour correspondre à tous les commentaires dans un script T-SQL

J'ai besoin d'une expression régulière pour capturer tous les commentaires dans un bloc de T-SQL. L'expression devra travailler avec la classe .Net Regex.

Disons que j'ai le texte T-SQL suivant: P>

-- This is Comment 1
SELECT Foo FROM Bar
GO

-- This is
-- Comment 2
UPDATE Bar SET Foo == 'Foo'
GO

/* This is Comment 3 */
DELETE FROM Bar WHERE Foo = 'Foo'

/* This is a
multi-line comment */
DROP TABLE Bar


6 commentaires

Cette réponse devrait aider - Stackoverflow.com/Questtions/653143/...


Comment géreriez-vous des commentaires / * / * niché? * / * /


@ ipr101 - J'ai passé un bon moment en regardant le poste que vous avez mentionné, mais sans chance. Je ne suis pas très bon aux expressions régulières. Je n'ai pas été en mesure de modifier l'exemple de sorte qu'il n'aura que les commentaires et aucune des déclarations SQL valides.


@Jnk - J'aimerais que tout le commentaire imbriqué, y compris les marqueurs extérieurs.


Les expressions régulières ne conviennent pas à cela. Vous avez besoin d'un analyseur


@Martinsmith - Merci pour la pointe solide. J'ai réellement trouvé un analyseur qui fonctionne très bien. Il fait partie du moteur de blog sous-texte et est son propre projet dans le code source: sous-texte.scripting. Phil Haack a écrit son propre blog post à ce sujet et pourquoi il l'a créée. Vérifiez-le: HAACKED.COM/Archive/2007/11/04/... . En outre, le code source: code.google.com/p/subtext . Téléchargement direct pour juste le composant de script: code.haacked.com/util/subtext.scripting. Zip . Merci encore pour votre aide!


8 Réponses :


18
votes

Cela devrait fonctionner:

(--.*)|(((/\*)+?[\w\W]+?(\*/)+))


6 commentaires

Non ça ne le fait pas. Cela ne prend pas en charge les commentaires imbriqués comme indiqué.


@FaileDDev - Cette déclaration visait à une question. Ce serait une bonne chose à avoir, pas vraiment une requête.


Cela ne supporte pas les alinéas


Voir ma réponse ci-dessous. Cela fonctionne avec des commentaires de bloc imbriqués. Stackoverflow.com/a/33947706/3606250


Si vous avez des chaînes qui contiennent ce qui serait autrement un commentaire SQL, cela correspondra-t-il aussi malheureusement, E.G.: Sélectionnez * de FOO Où A = 'Ceci a - tirets'


Je me rends compte que c'est un vieux fil, mais pour tous ceux qui arrivaient ici via un moteur de recherche, je voulais souligner que je devais échapper à la barre avant / pour faire ce travail, donc cela a fonctionné pour moi :. (-. *) | ((((\ / \ *) +? [\ w \ w] +? (\ * \ /) +)) Testez-le ici



6
votes

Utilisation de ce code: xxx pré>

avec l'entrée suivante: p>

-- This is Comment 1
-- This is
-- Comment 2
/* This is Comment 3 */
/* This is a
multi-line comment */
/* comment /* nesting */ of /* two */ levels supported */


1 commentaires

Cette regex ne correspond pas à un commentaire - s'il apparaît sur la dernière ligne d'une chaîne sans fuite \ n .



1
votes

Cela fonctionne pour moi: xxx

Il correspond à tous les commentaires commençant par - ou enfermé dans * / .. * / blocs


1 commentaires

Comme dans Votre question expressions régulières sont < b> pas approprié pour cela. par exemple. Sélectionnez '/ * Ce n'est pas un commentaire * /' de (SELECT 1 AS C) [/ * NOR CELA * /] est parfaitement valide TSQL.



9
votes

en PHP, j'utilise ce code pour mot note SQL (ceci est la version commentée -> x modificateur x): xxx pré>

version courte: p>

trim( preg_replace( '@(([\'"]).*?[^\\\]\2)|((?:\#|--).*?$|/\*(?:[^/*]|/(?!\*)|\*(?!/)|(?R))*\*\/)\s*|(?<=;)\s+@ms', '$1', $sql ) );


1 commentaires

Essayer de comprendre cette regex et je suis comme \ _ (ツ) _ / ¯



1
votes

Je vois que vous utilisez SQL Server de Microsoft (par opposition à Oracle ou MySQL). Si vous détendez l'exigence de regex, il est maintenant possible (depuis 2012) d'utiliser votre propre analyseur de Microsoft: xxx

voir Supprimer des commentaires de SQL


1 commentaires

J'ai essayé cette méthode et cela fonctionne assez bien, mais la performance souffre. J'ai comparé ma regex ( voir ma réponse ci-dessous ) à cet analyseur Microsoft et j'ai obtenu les mêmes résultats (sur plus de 3 mille scripts) mais avec une fraction de temps.



4
votes

J'ai fait cette fonction qui supprime tous les commentaires SQL, en utilisant des expressions ordinaires ordinaires forts>. Il élimine les commentaires de la ligne forts> (même quand il n'y a pas de chevrocheter après) et Block Commentaires forts> (même s'il y a des commentaires de bloc imbriqués). Cette fonction peut également Remplacer les littéraux forts> (utile si vous recherchez quelque chose à l'intérieur des procédures SQL, mais que vous souhaitez ignorer les chaînes).

Mon code était basé sur ce answer (qui concerne les commentaires C #), je devais donc changer de commentaires de ligne de "//" à "-", mais plus important encore, je devais réécrire le Bloquer les commentaires Regex (en utilisant Équilibrer des groupes forts>) car SQL permet aux commentaires des blocs imbriqués forts>, tandis que c #. P>

Aussi, j'ai cette " PRESERVOSITIONS STROND>" argument, qui au lieu de supprimer les commentaires qui remplissent simplement des commentaires avec WhitSpace. C'est utile si vous souhaitez conserver la position d'origine de chaque commande SQL, au cas où vous auriez besoin de manipuler le script d'origine tout en préservant les commentaires originaux. P>

Original:
[create table [/*] /* 
  -- huh? */
(
    "--
     --" integer identity, -- /*
    [*/] varchar(20) /* -- */
         default '*/ /* -- */' /* /* /* */ */ */
);
            go]


[create table [/*]    

(
    "--
     --" integer identity,      
    [*/] varchar(20)         
         default '*/ /* -- */'                  
);
            go]


[create table [/*]    

(
    "--
     --" integer identity,      
    [*/] varchar(20)         
         default '           '                  
);
            go]


11 commentaires

En prenant ceci à partir de votre code: Regex Rex = nouvelle regex (@ »/ * (?> / * (? ) | * / (? <- Niveau>) | (?! / * | * /).) + (? (Niveau) (?!))) * / ", Regexoption.Singline | Regexoption.CultureInvariance); MatchCollection Mcoll = Rex.Matches (Thestring, 0); Bandes tous les commentaires de bloc imbriqués. Merci. C'est le seul que j'ai trouvé cela fonctionne comme prévu.


David, je suis content que cela fonctionnait. Mais veuillez noter que l'utilisation de toutes les 6 regexs en même temps est importante, car un commentaire de blocage pourrait être situé à l'intérieur d'un littéral à chaîne (par exemple: Sélectionnez '/ * Ceci est un littéral * /' de Sys.Tables), ou même à l'intérieur d'une Commentaire de ligne. Donc, ma suggestion est de changer la fonction Lambda pour extraire exactement ce que vous voulez.


Ne semble pas fonctionner avec cette chaîne: / * Stuff avec des commentaires imbriqués / * wooooo * / wonder whut whut vient Next / * Woot 2 * / Créer Proc in Dis avec le cryptage * / Créer la procédure DBO.WOIOTNINNTU avec cryptage comme jeu SELECT * Du maître fin


Cela fonctionne: Regex Rex = nouvelle regex (@ "/ * (?> / * (? ) | * / (? <- Niveau>) | (? (? (? (? Niveau) (?!))) * / ", Regexoption.Singline | Regexoption.CultureInvariance | Regexoption.ignorepatternwhitePace);


Ceci est très bon, mais quand vous avez un commentaire comme celui-ci / * exec quelque_proc '123456789c', 'A86A23CE-F068-450B-9356-A21197B7A715 | CD7EF1CA-3247-492B-804 B-658C2473867D | B118E 687 -6CBB-4438-A407-8 0DE93995885 '* / Il supprimera tout sauf |


David, je viens de tester maintenant et ça marche pour moi. Utilisez-vous le code complet?


@Gayanranasinghe, tu as raison. Il y avait une erreur dans mon étant-ce quetExceptNewLines regex, il ne remplaçait pas le caractère de la pipe. Je viens de corriger la regex et je travaille maintenant. Merci pour l'alerte.


@Drizin Pouvez-vous consolider les deux regeures pour les commentaires de ligne unique en ajoutant l'option Regexoption.Multiline et en utilisant uniquement ce dernier?


Je n'obtiens pas le cidididentifiers pièce ici. Utilisation de Regexbuddy avec la syntaxe PCRE ou C #, (\ "" ((((\ "" \ "") | [^ ""]) * \ "") * \ "") ne correspond pas à Create Table "SELECT" ("Identité" non NULL , "commande" int non null);


@Jandoggen Je ne connais pas Regexbuddy, mais je suppose que c'est à propos de la citation correctement (puisque mon code ci-dessus est C #). J'ai essayé avec Ultrapico Expresso la regex suivante ("(((" ") | [^"]) * ") Et cela a fonctionné bien - cela pourrait identifier tous vos 3 identifiants cités (" Sélectionner "," identité "," ") Les contenus ne sont pas supprimés de manière incorrecte comme des commentaires.


Ah, bien sûr. Dans n'importe quel outil de regex ou dans ma mise en œuvre de Delphi, je n'ai pas besoin d'écrire "". Alors ça marche bien ;-)



1
votes

L'option suivante fonctionne bien - pg-minify , et non seulement pour PostgreSQL, mais Pour MS-SQL aussi.

Vraisemblablement, si nous supprimons les commentaires, cela signifie que le script n'est plus pour la lecture et la minifiant en même temps est une bonne idée.

Cette bibliothèque supprime tous les commentaires dans le cadre de la minification du script.


0 commentaires

0
votes

J'utilise ce code Java pour supprimer tous les commentaires SQL du texte. Il soutient des commentaires comme / * ... * /, --..., des commentaires imbriqués, ignore les commentaires à l'intérieur des chaînes citées xxx


0 commentaires