Méthode simple pour détecter de manière fiable le code dans le texte?

142

GMail dispose de cette fonctionnalité dans laquelle il vous avertira si vous essayez d'envoyer un e-mail qu'il pense avoir une pièce jointe.

Vouliez-vous joindre des fichiers?

Comme GMail a détecté la chaîne see the attacheddans l'e-mail, mais pas de pièce jointe, il m'a averti par une boîte de dialogue OK / Annuler lorsque je clique sur le bouton Envoyer.

Nous avons un problème connexe sur Stack Overflow. C'est-à-dire que lorsqu'un utilisateur entre un message comme celui-ci :

mon problème est que je dois changer la base de données mais je ne veux pas créer 
une nouvelle connexion. exemple:

DataSet dsMasterInfo = new DataSet ();
Database db = DatabaseFactory.CreateDatabase ("ConnectionString");
DbCommand dbCommand = db.GetStoredProcCommand ("uspGetMasterName");

Cet utilisateur n'a pas formaté son code en tant que code!

C'est-à-dire qu'ils n'ont pas indenté de 4 espaces par Markdown, ni utilisé le bouton de code (ou le raccourci clavier ctrl+ k) qui le fait pour eux.

Ainsi, notre système accepte de nombreuses modifications dans lesquelles les utilisateurs doivent entrer et formater le code manuellement pour les utilisateurs qui sont en quelque sorte incapables de le comprendre. Cela conduit à beaucoup de mal au ventre . Nous avons amélioré l'aide de l'éditeur à plusieurs reprises, mais nous ne savons pas quoi faire ensuite, à moins de nous rendre chez l'utilisateur et d'appuyer sur les boutons appropriés de son clavier.

C'est pourquoi nous envisageons un avertissement de style Google GMail:

Vouliez-vous dire poster du code?

Vous avez écrit des éléments qui ressemblent à du code, mais vous ne les avez pas formatés en indentant 4 espaces, à l'aide du bouton de code de la barre d'outils ou de la commande de formatage du code ctrl+ k.

Cependant, pour présenter cet avertissement, nous devons détecter la présence de code que nous pensons être du code non formaté dans une question . Qu'est-ce qu'un moyen simple et semi-fiable de faire cela?

  • Dans Markdown , le code est toujours mis en retrait par 4 espaces ou par des backticks, ainsi tout élément correctement formaté peut être immédiatement ignoré de la vérification.
  • Ceci n'est qu'un avertissement et ne s'appliquera qu'aux utilisateurs peu réputés posant leurs premières questions (ou fournissant leurs premières réponses), de sorte que certains faux positifs sont acceptables, à condition qu'ils ne dépassent pas 5%.
  • Les questions sur le dépassement de capacité peuvent être dans toutes les langues, bien que nous puissions de manière réaliste limiter notre contrôle aux, disons, les «dix langues les plus importantes». Selon la page des balises, C #, Java, PHP, JavaScript, Objective-C, C, C ++, Python, Ruby.
  • Utilisez le dump de données creative commons de Stack Overflow pour auditer votre solution potentielle (ou choisissez simplement quelques questions dans les 10 balises les plus importantes de Stack Overflow) et voyez comment cela se passe.
  • Le pseudo-code convient, mais nous utilisons c # si vous voulez être très amical.
  • Le plus simple sera le mieux (tant que cela fonctionne). BAISER! Si votre solution nécessite que nous essayions de compiler des messages dans 10 compilateurs différents, ou une armée de personnes pour entraîner manuellement un moteur d'inférence bayésien, ce n'est… pas exactement ce que nous avions en tête.
Jeff Atwood
la source
34
Je pense que si vous affichez toujours l'avertissement s'il n'y a pas d'indentation, vous serez bien en dessous de la limite d'erreur de 5%. Ce n'est que la moitié d'une blague.
Konrad Rudolph Le
59
@ Konrad Cela fonctionnerait encore mieux si le message était le suivant: "Soit il manque des exemples de code dans votre question qui aideraient les autres à le comprendre, soit vous avez oublié de les indenter correctement". Cela devrait couvrir 99% de tous les cas.
Thorsten Müller
3
C’est une bonne question mais j’ai le sentiment qu’elle n’a pas de réponse. Vous me montrez un système anti-imbécile et je vais vous montrer un meilleur imbécile. Même si ce problème pouvait être traité par CODE, peut-être que non. Ce sont ces personnes ignorantes qui ne peuvent pas être dérangées de poser une bonne question qui RUINENT ce site pour des personnes comme moi qui posent les bonnes questions ET apportent les bonnes réponses à mon humble avis.
maple_shaft
2
Un modèle courant que j'ai vu est un bloc de code correctement mis en retrait, mais où les première et dernière lignes (généralement seules deux, parfois plus lorsque plusieurs fonctions sont affichées, par exemple) ne sont pas étiquetées en tant que code. Cela devrait probablement être détecté aussi.
3Doubloons
3
Sur une note de côté, le texte de confirmation de GMail est plutôt déroutant. Si votre réponse à la première question est "oui", alors la réponse à la deuxième question est "non" ...
pimvdb Le

Réponses:

147

Une solution appropriée consisterait probablement en un modèle savant / statistique, mais voici quelques idées amusantes:

  1. Points-virgules à la fin d'une ligne . Cela seul attraperait tout un tas de langues.
  2. Les parenthèses suivant le texte sans espace pour le séparer: myFunc()
  3. Un point ou une flèche entre deux mots: foo.bar = ptr->val
  4. Présence d'accolades, crochets: while (true) { bar[i]; }
  5. Présence de la syntaxe "comment" (/ *, //, etc): /* multi-line comment */
  6. Caractères / opérateurs peu communs: +, *, &, &&, |, ||, <, >, ==, !=, >=, <=, >>, <<, ::, __
  7. Exécutez votre surligneur de syntaxe sur le texte. Si cela finit par en mettre en évidence un pourcentage élevé, c'est probablement du code.
  8. texte camelCase dans le post.
  9. parenthèses, accolades et / ou crochets imbriqués.

Vous pouvez suivre le nombre de fois où chacun de ces éléments apparaît et les utiliser dans un algorithme d'apprentissage automatique comme Perceptron , comme le fait SpamAssassin.

Yevgeniy Brikman
la source
25
Astuces: 3 a un poids très faible, car un point entre les mots peut être le résultat d'une faute de frappe. 5 ne doit pas correspondre aux URL. Pour 6, l'esperluette est également fréquemment utilisée en dehors du contexte du code. Cela pourrait également alourdir ce caractère. Vérifiez bien si le surligneur fonctionne, car il peut mettre en évidence un texte non codé comme je le vois parfois dans Notepad ++.
Tamara Wijsman le
8
êtes le . comme une faute de frappe - il n'y aurait aucun mal à signaler cela comme l'auteur devrait le modifier de toute façon.
user151019
4
En outre, des mots-clés spécifiques à de nombreuses langues peuvent aider: WHILE, ELSE, IF, LOOP, BREAK, etc.
JoséNunoFerreira, le
6
Ajouter "Utilisation de $ avant les mots non numériques: $ var est commun en Perl et PHP (et Ruby?)."
PhiLho
4
Vous ne détecterez pas mon SELECT DISTINCT name FROM people WHERE id IS NOT NULL.
Benoit
54

Je serais curieux de voir quelles sont les mesures moyennes de l’anglais écrit d’un côté et du code de l’autre.

  • longueur des paragraphes
  • longueur des lignes
  • taille des mots
  • caractères utilisés
  • rapport entre caractères alphabétiques, numériques et autres symboles
  • nombre de symboles par mot
  • etc.

Peut-être que cela seul pourrait déjà faire la différence entre le code et le reste. Au moins, je pense que le code, quelle que soit la langue, montrerait des métriques sensiblement différentes dans de nombreux cas.

La bonne nouvelle est que vous disposez déjà de nombreuses données pour construire vos statistiques.


Ok, je suis de retour avec quelques données pour étayer mes hypothèses. :-)

Je l' ai fait un test rapide et sale sur votre poste et sur le premier post j'ai trouvé sur StackOverflow , avec un outil assez avancé: wc.

Voici ce que j'ai eu après avoir exécuté wcla partie texte et la partie code de ces deux exemples:

Regardons d'abord la partie anglaise :

  • La partie anglaise de votre message (2635 caractères, 468 mots, 32 lignes)
    • 5 caractères / mot, 82 caractères / ligne, 14 mots / ligne
  • La partie anglaise de l'autre message (1499 caractères, 237 mots, 12 lignes)
    • 6 caractères / mot, 124 caractères / ligne, 19 mots / ligne

Assez similaire, vous ne pensez pas?

Regardons maintenant la partie code !

  • La partie code de votre message (174 caractères, 13 mots, 3 lignes)
    • 13 caractères / mot, 58 caractères / ligne, 4 mots / ligne
  • La partie code de l'autre article (4181 caractères, 287 mots, 151 lignes)
    • 14 caractères / mot, 27 caractères / ligne, 2 mots / ligne

Vous voyez à quel point ces métriques ne sont pas si différentes, mais plus important encore, à quel point elles sont différentes des métriques anglaises? Et ceci utilise simplement un outil limité. Je suis maintenant sûr que vous pouvez obtenir quelque chose de vraiment précis en mesurant plus de mesures (je pense en particulier aux statistiques sur les caractères).

Je peux haz cookie?

Julien Guertault
la source
6
La longueur des lignes, en particulier si vous excluez les puces et recherchez des lignes en cluster d'une longueur inférieure à une longueur particulière contenant une ponctuation spécifique, semble être une bonne mesure.
Jon Hopkins
Cela fonctionnerait pour des blocs de code, mais il semblerait beaucoup plus difficile de rechercher un cdde en ligne. Je ne sais pas à quel point cela compte, mais le problème le plus important est de gros blocs de code non formaté de toute façon.
cHao
3
Pas de cookies. Le lien dans votre message est 404.
james.garriss
@ james.garriss: Internet a volé ma jarre à biscuits. :( Merci pour la notification cependant.
Julien Guertault
23

En règle générale, les chaînes de Markov sont utilisées pour générer du texte, mais elles peuvent également être utilisées pour prédire la similarité du texte (d' après CE, Shannon 1950 ) avec un modèle formé. Je recommande plusieurs chaînes de Markov.

Pour chaque langue prévalente, formez une chaîne de Markov sur un grand échantillon de code représentatif de la langue. Ensuite, pour un poste de débordement de pile pour lequel vous souhaitez détecter du code, procédez comme suit pour chacune des chaînes:

  • Boucle à travers les lignes dans le post.
    • Déclarez deux variables: ACTUAL = 1.0 et HIGHEST = 1.0
    • Boucle à travers chaque caractère de la ligne.
      • Pour chaque caractère, trouvez la probabilité dans la chaîne de Markov que le caractère actuel soit celui qui suit les N caractères précédents. Définissez ACTUAL = ACTUAL * PROB 1 . Si le caractère actuel n'est pas présent dans la chaîne, utilisez une valeur minuscule pour PROB 1 , telle que 0.000001.
      • Maintenant, trouvez le caractère le plus susceptible (c'est-à-dire la probabilité la plus élevée) de suivre les N caractères précédents. Réglez HIGHEST = HIGHEST * PROB 2 .
      • Evidemment, PROB 2 > = PROB 1

Pour chaque ligne, vous devez avoir une valeur réelle et la plus haute. Divisez ACTUAL par HIGHEST. Cela vous donnera le score de remise en forme quant à savoir si une ligne particulière est un code source. Cela associerait un numéro à chacune des lignes de l'exemple que vous avez donné:

my problem is I need to change the database but I don't won't to create // 0.0032
a new connection. example: // 0.0023

DataSet dsMasterInfo = new DataSet(); // 0.04
Database db = DatabaseFactory.CreateDatabase("ConnectionString");   // 0.05
DbCommand dbCommand = db.GetStoredProcCommand("uspGetMasterName");  // 0.04

Enfin, vous devrez sélectionner un seuil pour déterminer quand il y a du code dans le message. Cela pourrait simplement être un nombre sélectionné par l'observation qui donne de hautes performances. Il pourrait également prendre en compte le nombre de lignes avec un score élevé.

Entraînement

Pour vous entraîner, procurez-vous un grand échantillon représentatif de code dans la langue. Ecrivez un programme à lire en boucle sur le texte du code et associez chaque N-gramme du fichier (la plage de N doit être paramétrée) à la fréquence statistique du caractère suivant. Cela donnera plusieurs états possibles des caractères qui suivent le bigramme, chacun associé à une probabilité. Par exemple, bigram "()" pourrait avoir les probabilités de caractère suivantes:

"()" 0.5-> ";"
"()" 0.2-> "."
"()" 0.3-> "{"

La première doit être lue, par exemple, comme suit: "La probabilité qu'un point-virgule suive une parenthèse vide est de 0.5."

Pour la formation, je recommande N-grammes de taille deux à cinq. Lorsque j'ai fait des recherches à ce sujet , nous avons constaté que les tailles N-grammes deux à cinq fonctionnaient bien pour l'anglais. Étant donné que le code source est en grande partie en anglais, je suggérerais de commencer par cette plage, puis de procéder à un ajustement pour trouver les valeurs de paramètre optimales à mesure que vous trouvez ce qui fonctionne.

Une mise en garde: le modèle va être affecté par des identifiants, des noms de méthodes, des espaces, etc. Par exemple, vous pouvez réduire tous les espaces inutiles. La présence d'espaces dans l'entrée (la publication Stack Overflow) peut également être ignorée. Vous pouvez également ignorer la casse alphabétique, ce qui serait plus résilient face aux différentes conventions de dénomination des identifiants.

Au cours de mes recherches , nous avons constaté que nos méthodes fonctionnaient bien pour l'espagnol et l'anglais. Je ne vois pas pourquoi cela ne fonctionnerait pas aussi bien pour le code source. Le code source est encore plus structuré et prévisible que le langage humain.

Matthew Rodatus
la source
2
Le seul problème que je prévois est que les probabilités seront beaucoup plus petites que dans votre exemple de jouet. Étant donné l'instabilité numérique, cela signifie que toutes les probabilités sont bientôt égales à 0. L'utilisation des probabilités du journal résout ce problème. De plus, j'utiliserais des jetons plus grands (c.-à-d. Pas des caractères, mais des mots / ponctuation).
Konrad Rudolph le
2
@ Konrad: L'idée ici n'est pas de tester les probabilités absolues: c'est de tester les probabilités relatives. Pour chaque ligne, le texte de cette ligne est-il plus susceptible d'avoir été généré par un modèle anglais ou par un modèle langage codé?
Ken Bloom
5
Vous pouvez former ce modèle sur des publications SO existantes (notamment parce que vous devrez peut-être rendre compte de la syntaxe Markdown). Si vous supposez que la plupart des messages sont correctement formatés (ou si vous sélectionnez un grand nombre de messages, de l'ordre de dizaines de milliers, pour supprimer les messages qui ne sont pas correctement formatés), vous supposez que les éléments non formatés en code sont en anglais et les éléments formatés en code sont des codes, vous pouvez vous entraîner à partir de réponses SO réelles.
Ken Bloom
1
Un tutoriel sur la procédure à suivre (utilisation de LingPipe en Java) est disponible sur le site Web de LingPipe . À la fin du didacticiel, vous trouverez un certain nombre de documents sur les techniques permettant de résoudre ce problème. Je suggère de les lire.
Ken Bloom
1
Il est intéressant de voir que la solution de pointe ne compte que très peu de voix et qu'elle est nettement inférieure à toutes les solutions ad-hoc qui, certes, pourraient suffire, mais reposent beaucoup sur des cas spéciaux et sont intrinsèquement sujettes à l'overfitting.
Konrad Rudolph
13

Puis-je suggérer une approche radicalement différente? Sur SO, la seule langue humaine autorisée est l'anglais, de sorte que tout ce qui n'est pas anglais a 99,9% de chances d'être un extrait de code .

Ma solution serait donc la suivante: utilisez l’un des nombreux vérificateurs de la langue anglaise (assurez-vous simplement qu’ils signalent également, outre les fautes d’orthographe, des erreurs de syntaxe telles que les doubles points ou les symboles non linguistiques tels que #ou ~). Ensuite, toute ligne / paragraphe générant une grande quantité d’erreurs et d’avertissements devrait déclencher le message "is this code?" question.

Cette approche peut également être adaptée pour les sites StackExchange utilisant des langues autres que l'anglais, bien sûr.

Juste mes 2 ¢ ...

mac
la source
16
Le problème est que beaucoup de questions entrantes ne sont pas anglais non plus (bien qu'elles lui ressemblent).
Brendan Long
3
@Brendan - Ajout de l'avantage de cette proposition ensuite: soulignez (ou mettez en surbrillance) les erreurs commises dans les parties du message probablement destinées à être l'anglais et aidez l'écrivain à écrire ... en anglais! ;)
mac
1
Je suis néerlandais et tout ce que je code est en anglais, mais les commentaires ne le sont pas (selon le projet). Donc, le non-anglais doit être un code ne suffirait pas. Cela ou tu veux dire que l'anglais cassé doit être un code.
Ivo Limmen
@ Ivo - Mon commentaire a été adressé en plaisantant au numéro anglais cassé! ;) Cependant, je dirais qu'avec ma proposition, les commentaires dans une autre langue fonctionneraient parfaitement ... Les commentaires de blocage OTOH en anglais ne déclencheront pas le "is this code?" question, mais c'est très bien parce que le code pour lequel le commentaire a été écrit l'aurait déjà déclenché ...
mac
11

Je vais probablement obtenir quelques votes négatifs pour cela, mais je pense que vous abordez cette question sous un mauvais angle.

Cette ligne m'a eu:

les gens doivent entrer et formater manuellement le code pour les personnes qui sont en quelque sorte incapables de le comprendre

OMI, ce point de vue est un peu arrogant. Je trouve cela souvent dans la conception de logiciels, où les programmeurs et les concepteurs sont ennuyés par les utilisateurs qui ne savent pas comment utiliser le logiciel correctement, alors que le problème n'est pas l'utilisateur mais le logiciel lui-même - ou l'interface utilisateur du moins.

La cause première de ce problème n'est pas l'utilisateur mais le fait qu'il ne leur est pas évident de pouvoir le faire.

Que diriez-vous d'un changement dans l'interface utilisateur pour rendre cela plus évident? Ce sera sûrement:

  1. plus évident pour les nouveaux utilisateurs exactement ce qu'ils doivent faire
  2. plus facile à construire que d'écrire des algorithmes complexes pour détecter la logique de code d'une multitude de langages

Exemple:

entrez la description de l'image ici

matt_asbury
la source
26
En fait, cette OMI impose des questions médiocres telles que "J'ai un problème, aidez-moi, le code est en dessous" - le code doit rarement être séparé de la question. Les meilleures questions vont comme ceci "Je veux y parvenir et j'ai écrit ces deux lignes de code, mais l'effet est le suivant, quel est le problème" - il y a très peu de code fortement imbriqué dans un langage simple.
Sharptooth
4
Votre observation racine est correct , mais le diagnostic est encore mal: en fait, Jeff est d' essayer d'améliorer l'interface utilisateur via cette approche. En outre, l'interface utilisateur actuelle a déjà subi plusieurs cycles et, bien que je ne doute pas qu'elle puisse être améliorée (de façon drastique), je doute que cela puisse aider contre les idiots paresseux. Ni votre solution proposée. @sharptooth a ce couvert.
Konrad Rudolph
2
Je voudrais +1 pour avoir pensé à la boîte, mais je ne suis pas d'accord avec la suggestion spécifique, car l'affichage de "code de support" impose un flux de questions qui peut ne pas être naturel. Je n'ai jamais simplement jeté du code au bas de ma question. Je poste presque toujours une intro, le code exemple, puis la question proprement dite. Si vous acceptez le principe selon lequel le code en ligne est essentiel, un certain type de formatage est nécessaire - le formatage doit être entré par l'utilisateur ou recommandé par le système. Et c'est exactement ce que Jeff demande à faire.
Nicole
1
@ Konrad: En plus de mon commentaire ci-dessus et en réponse au vôtre, je ne crois pas que Jeff améliore l'interface utilisateur en empruntant cette voie, mais en traitant simplement les symptômes d'un problème sous-jacent. Si l'interface utilisateur était améliorée afin que l'erreur ne puisse pas être commise, la solution consistant à alerter l'utilisateur ne serait pas nécessaire. Je ne me fais aucune illusion sur le fait que mon exemple est la solution finale, mais il faut réfléchir à la question "présentons-nous cela de la meilleure façon possible?".
matt_asbury
1
La phrase simple s'il vous plaît marquer le code en utilisant le {}bouton autour de la zone de texte pourrait être suffisant.
Paŭlo Ebermann le
11

Le pseudo-code constituerait un véritable défi car tout langage de programmation dépend de caractères spéciaux tels que '[]', ';', '(') ', etc. Il suffit de compter l'occurrence de ces caractères spéciaux. Tout comme vous détecteriez un fichier binaire (plus de 5% d'un échantillon contient la valeur d'octet 0).

Ivo Limmen
la source
J'améliorerais cela autant que d'avoir des groupes de ces caractères spéciaux comme [] (); {} =. Chaque ligne contenant plus de 2-3 de ces groupes est une ligne de code.
Honza
... et recherchez également des chaînes communes dans les langues les plus courantes, par exemple "= someword ();" pour la plupart des langages avec accolades, une syntaxe de type XML telle que "<quelque chose>" et "<ab: cde>", ainsi que d'autres chaînes communes dans d'autres langages. Je crois qu'une table de recherche de syntaxe commune serait une bonne solution, car vous pouvez la développer lorsque vous trouvez de nouveaux langages à implémenter.
Arve Systad
Vous devriez probablement laisser tomber le pseudo-code. Certaines personnes aiment l'écrire en tant que langue de style C, mais d'autres personnes utiliseront un anglais simple avec quelque chose qui ressemble plus à VB6
James P.
4

Je pense que vous devrez peut-être cibler cela uniquement sur des langues spécifiques. En général, le problème est probablement insoluble, car vous pouvez obtenir des langues assez similaires à l'anglais (par exemple, inform7 ). mais heureusement, les plus utilisés pourraient être couverts assez facilement.

La première chose que je ferais serait de rechercher la séquence "; \ n" qui vous conviendrait parfaitement pour C, C ++, Java, C # et tout autre langage utilisant une syntaxe similaire et très simple. Il est également moins susceptible d’être utilisé en anglais qu’un; sans nouvelle ligne

jk.
la source
plus peut-être une abondance d'accolades; p
Marc Gravell
1
Comme Jeff le dit dans son post, ils ne viseraient probablement que les langues principales. Et dans tous les cas, je soupçonne que les nouveaux utilisateurs (à qui cette fonctionnalité est destinée) seront plus susceptibles de publier du C # ou du Javascript que, par exemple, INTERCAL ;-)
Ben
Oui, mais cela ne fonctionnerait pas avec le langage de programmation BRAINFUCK ou BLANK. ;-)
Ivo Limmen le
4

Quelqu'un a mentionné regarder les balises, puis la syntaxe, mais cela a été éliminé parce que cela s'adresse aux nouveaux utilisateurs.

Une meilleure solution possible consisterait à rechercher des noms de langue dans le corps de la question, puis à appliquer la même stratégie. Si je mentionne "Javascript", "Java" ou "C #", il y a de fortes chances que ce soit le propos de la question et que le code de la question soit susceptible d'être rédigé dans ce langage.

Omar Kooheji
la source
Surtout si le titre est quelque chose comme "vb c # .net point net aidez-moi à m'aider !!!"
NickAldwin le
1

Tout d’abord, vérifiez le correcteur orthographique, il trouvera très peu de mots anglais corrects, mais il devrait y avoir beaucoup de mots que le vérificateur orthographique suggérera de scinder.

Ensuite, il y a des signes de ponctuation / spéciaux non typiques de l'anglais ordinaire, typiques du code:

  • something(); ne peut tout simplement pas être un anglais simple;
  • $somethingsomethingn'est pas tout numérique;
  • -> entre les mots sans espaces;
  • . entre les mots sans espace;

Bien sûr, pour que cela fonctionne bien, vous pouvez avoir un classificateur bayésien construit sur ces caractéristiques.

vartec
la source
1
Détecter une ligne non en retrait contenant (); serait une bonne raison de suggérer le message.
Quel correcteur orthographique ne s'étouffera pas avant que le code ne soit collé?
Tim Post
Avec quelques messages écrits par des écrivains anglais non natifs, le correcteur orthographique s'étouffera à chaque mot ...
PhiLho le
@Ph: ces questions / réponses ne sont de toute façon pas acceptées sur SO.
vartec
1

il existe plusieurs ensembles de langages qui partagent une syntaxe similaire. la plupart des langages ont été influencés par quelques langages, donc les langages [AMPL, AWK, csh, C ++, C--, C #, Objective-C, BitC, D, Go, Java, JavaScript, Limbo, LPC, Perl, PHP, Pike, Processing [ont tous été influencés par C, donc si vous détectez C, vous détecterez probablement toutes ces langues. il vous suffit donc d'écrire un modèle simple pour détecter ces ensembles de langues.

Je voudrais également diviser le texte en blocs, car la plupart du code sera divisé en deux nouvelles lignes ou similaire aux autres blocs de texte de l'article.

cela peut être facile à faire avec javascript (un échantillon incomplet très simple pour la famille c):

var txt = "my problem is I need to change the database but I don't won't to create a new connection. example:\n\nDataSet dsMasterInfo = new DataSet();Database db = DatabaseFactory.CreateDatabase(&quot;ConnectionString&quot;);DbCommand dbCommand = db.GetStoredProcCommand(&quot;uspGetMasterName&quot;);";
var blocks = txt.split(/\n\n/gi); console.dir(blocks);
var i = blocks.length;
var cReg = /if\s*\(.+?\)|.*(?:int|char|string|short|long).*?=.+|while\s*\(.+?\)/gi;

while ( i-- ){
   var current = blocks[i];
   if ( cReg.test( current ) ){
      console.log("found code in block[" +  i + "]");
   }
}
Michael van der Weg
la source
0

Comptez simplement les mots / caractères de ponctuation pour chaque ligne. Anglais aura tendance à avoir 4 ou plus, code moins de 2.

Le paragraphe ci-dessus contient 18 mots et 4 caractères de ponctuation, par exemple. Ce paragraphe contient 19 mots et 4 signes de ponctuation, donc à la hauteur des attentes.

Bien sûr, cela devrait être testé par rapport aux questions des débutants dont la langue maternelle est l'anglais médiocre, et il se peut que dans ces cas, les statistiques soient faussées.

Je m'attends à ce que [non-espace]. [Espace ou nouvelle ligne] soit très rare dans le code, mais courant en anglais, donc cela pourrait être compté comme des mots, pas de ponctuation.

Je pense que le plus gros problème sera le code en ligne, où quelqu'un posera une question comme celle-ci:

Si je dis pour (i = 0; i> 100; i ++) {} qu'est-ce que cela signifie?

C'est du code et de l'anglais, et devrait être marqué comme avec des ticks arrière:

Si je dis for (i=0; i>100; i++) {}ce que ça veut dire?

Rjmunro
la source
0

Je pense que vous devriez d’abord faire une distinction entre le code (suffisamment) formaté qui n’a besoin que d’être réellement désigné comme tel et le code (trop) mal formaté, qui nécessite de toute façon un formatage manuel.

Le code formaté a des lignes de séparation et une indentation. C'est-à-dire que si une ligne est précédée d'une seule ligne de séparation, vous avez un bon candidat. S'il y a des espaces blancs de tête en plus, vous avez un très bon candidat.

Le texte normal utilise deux lignes de séparation ou deux espaces et une ligne de séparation pour la mise en forme. Il existe donc un critère de distinction clair.

Dans le code LISP, vous ne trouverez pas de point-virgule, dans le code Ruby, vous ne trouverez peut-être pas de parenthèse, dans le pseudo-code, vous ne trouverez peut-être pas grand-chose du tout. Mais dans n'importe quelle langue (non-ésotérique), vous trouverez un code correct à mettre en forme avec des lignes de séparation et une indentation. Il n'y a rien d'aussi universel que ça. En fin de compte, le code est écrit pour être lu par des humains.

Alors, commencez par rechercher des lignes de code potentielles . En outre, les lignes de code sont généralement regroupées. Si vous en avez un, il y a de fortes chances que celui en haut ou en bas soit également une ligne de code.

Une fois que vous avez sélectionné des lignes de code potentielles, vous pouvez les comparer à des critères quantifiables et choisir un seuil :

  • fréquence de caractères autres que des mots
  • fréquence d'identifiants: mots très courts ou très longs avec le style CamelCase ou under_score
  • répétition de mots peu communs

De plus, maintenant qu'il y a des programmeurs et des cs, la portée de stackoverflow est clairement réduite. On pourrait envisager de désigner toutes les étiquettes de langue comme des langues. Et lors de la publication, il vous sera demandé de choisir au moins une étiquette de langue, de choisir l' language-agnosticétiquette ou de l'omettre explicitement.

Dans le premier cas, vous savez quelles langues rechercher, dans le second, vous pouvez rechercher du pseudo-code et dans le dernier cas, il n'y aura probablement pas de code, car il s'agit d'une question de technologie ou cadre ou tel.

back2dos
la source
0

Vous pouvez créer un analyseur pour chaque langue que vous souhaitez détecter (les définitions de langue pour ANTLR sont généralement faciles à trouver), puis exécuter chaque ligne de la question dans chaque analyseur. Si une ligne est correctement analysée, vous avez probablement du code.

Le problème, c’est que certaines phrases anglaises (langage naturel) peuvent être analysées sous forme de code. Par conséquent, vous pouvez également inclure certaines des autres idées ou limiter les résultats positifs uniquement si plus d’une ou deux lignes consécutives s’analysent correctement avec le même analyseur de langage.

L’autre problème potentiel est que cela ne détectera probablement pas le pseudocode, mais c’est possible.

Jeff Knecht
la source
Les gens ont souvent des erreurs de syntaxe dans leur code (et posent des questions à ce sujet).
Paŭlo Ebermann le
0

Ce qui est peut-être le plus sûr pour l'avenir et qui nécessite le moins d'ajustement manuel à long terme, à mesure que d'autres langages (qui ont un aspect quelque peu différent des langages de programmation utilisés actuellement) deviennent plus populaires et que les langages actuellement utilisés deviennent moins populaires, c'est à faire quelque chose comme ce que fait Google Translate (voir le paragraphe "Comment ça marche?"), au lieu de chercher certaines choses comme ab et a (), etc.

En d'autres termes, au lieu de penser manuellement aux motifs à rechercher dans le code, l'ordinateur peut le résoudre lui-même . Cela peut être fait en ayant

  1. beaucoup de code dans de nombreux langages de programmation

    • Suggestion: prélevez automatiquement des échantillons de code dans des référentiels de code source basés sur le Web, tels que Google Code ou Github, ou même dans des éléments de Stackoverflow déjà marqués comme code.

    • Remarque: il peut être judicieux d’analyser les commentaires de code.

  2. beaucoup de texte anglais tiré d'articles sur le web

    • bien que ce ne soit pas des articles sur la programmation (sinon ils peuvent avoir du code et mélanger le système :-))

et avoir un certain type d'algorithme trouve automatiquement dans le code des modèles qui ne sont pas en anglais, et inversement, et utilise ces modèles pour détecter ce qui est du code et ce qui n'est pas du code en exécutant l'algorithme sur des publications.

(Cependant, je ne suis pas sûr de savoir comment fonctionnerait un tel algorithme. D'autres réponses à la question actuelle pourraient contenir des informations utiles à cet égard.)

Ensuite, le système peut ré-analyser le code de temps en temps pour prendre en compte les modifications apportées à la façon dont le code apparaît à cet instant précis.

Abafei
la source