Prosta metoda niezawodnego wykrywania kodu w tekście?


142

Gmail ma tę funkcję, gdzie będzie ostrzec jeśli spróbujesz wysłać wiadomość e-mail, że myśli mogą mieć zajęcia.

Czy chciałeś dołączyć pliki?

Ponieważ Gmail wykrył ciąg see the attachedw wiadomości e-mail, ale nie ma rzeczywistego załącznika, ostrzega mnie w oknie dialogowym OK / Anuluj po kliknięciu przycisku Wyślij.

Mamy podobny problem z przepełnieniem stosu. To znaczy, gdy użytkownik wprowadza post podobny do tego :

mój problem polega na tym, że muszę zmienić bazę danych, ale nie chcę jej tworzyć 
nowe połączenie. przykład:

DataSet dsMasterInfo = new DataSet ();
Baza danych db = DatabaseFactory.CreateDatabase („ConnectionString”);
DbCommand dbCommand = db.GetStoredProcCommand („uspGetMasterName”);

Ten użytkownik nie sformatował swojego kodu jako kodu!

Oznacza to, że nie wcięli się o 4 spacje na Markdown, ani nie używają przycisku kodu (lub skrótu klawiaturowego ctrl+ k), który robi to za nich.

Dlatego nasz system akceptuje wiele zmian, w których ludzie muszą wejść i ręcznie sformatować kod dla osób, które w jakiś sposób nie są w stanie tego zrozumieć. Prowadzi to do mnóstwa brzucha . Ulepszyliśmy kilka razy pomoc edytora, ale po przejechaniu do domu użytkownika i naciśnięciu odpowiednich przycisków na klawiaturze nie mamy pojęcia, co dalej.

Właśnie dlatego rozważamy ostrzeżenie w stylu Google GMail:

Miałeś na myśli kod pocztowy?

Napisałeś rzeczy, które naszym zdaniem wygląda jak kod, ale nie sformatować go jako kodu przez 4 spacje wcięć za pomocą przycisku paska narzędzi lub kodu ctrl+ kkod polecenia formatowania.

Jednak przedstawienie tego ostrzeżenia wymaga od nas wykrycia w naszym pytaniu pytania, które naszym zdaniem jest niesformatowanym kodem . Jaki jest prosty, częściowo niezawodny sposób na zrobienie tego?

  • Według Markdown kod jest zawsze wcięty o 4 spacje lub w backticks, więc wszystko poprawnie sformatowane może zostać natychmiast odrzucone z czeku.
  • Jest to tylko ostrzeżenie i będzie miało zastosowanie tylko do użytkowników o niskiej reputacji, którzy zadają pierwsze pytania (lub udzielają pierwszych odpowiedzi), więc niektóre fałszywe trafienia są OK, o ile wynoszą około 5% lub mniej.
  • Pytania dotyczące przepełnienia stosu mogą być w dowolnym języku, chociaż możemy realistycznie ograniczyć naszą kontrolę do, powiedzmy, „wielkich dziesięciu” języków. Na stronie tagów, która byłaby C #, Java, PHP, JavaScript, Objective-C, C, C ++, Python, Ruby.
  • Skorzystaj ze zrzutu wspólnych danych kreacji Przepełnienie stosu, aby skontrolować potencjalne rozwiązanie (lub po prostu wybierz kilka pytań w 10 najważniejszych tagach Przepełnienie stosu) i sprawdź, jak to działa.
  • Pseudokod jest w porządku, ale używamy c #, jeśli chcesz być wyjątkowo przyjazny.
  • Im prościej, tym lepiej (o ile działa). POCAŁUNEK! Jeśli twoje rozwiązanie wymaga od nas próby skompilowania postów w 10 różnych kompilatorach lub armii ludzi do ręcznego trenowania bayesowskiego silnika wnioskowania, to ... nie dokładnie to mieliśmy na myśli.

34
Myślę, że jeśli zawsze wyświetlasz ostrzeżenie, jeśli nie ma wcięcia, będziesz znacznie poniżej 5% limitu błędów. To tylko połowa oznacza żart.
Konrad Rudolph

59
@Konrad Działałoby to jeszcze lepiej, gdyby komunikat brzmiał: „Albo w twoim pytaniu brakuje próbek kodu, które pomogłyby innym zrozumieć, albo zapomniałeś je odpowiednio wciąć”. Powinno to obejmować 99% wszystkich przypadków.
thorsten müller

3
To DOBRE pytanie, ale czuję, że nie ma na nie odpowiedzi. Pokażesz mi system odporny na idioty, a ja pokażę ci lepszego idioty. Nawet jeśli ten problem mógłby zostać rozwiązany przez CODE, być może nie powinien? To ci nieświadomi ludzie, którym nie przeszkadza zadawanie PRAWIDŁOWYCH PYTAŃ, RUINUJĄ tę stronę dla ludzi takich jak ja, którzy zadają właściwe pytania i udzielają prawidłowych odpowiedzi IMHO.
wałek klonowy

2
Typowy wzorzec, który widziałem, to blok kodu, który sam był odpowiednio wcięty, ale gdzie pierwsza i ostatnia linia (zwykle tylko te dwie, czasem więcej, gdy na przykład pokazuje wiele funkcji), nie są oznaczone jako kod. To też prawdopodobnie powinno zostać wykryte.
3Doubloons

3
Na marginesie tekst potwierdzenia Gmaila jest dość mylący. Jeśli twoja odpowiedź na pierwsze pytanie brzmi „tak”, to odpowiedź na drugie pytanie brzmi „nie” ...
pimvdb

Odpowiedzi:


147

Właściwe rozwiązanie to prawdopodobnie wyuczony / statystyczny model, ale oto kilka zabawnych pomysłów:

  1. Średniki na końcu linii . Już samo to złapałoby całą masę języków.
  2. Nawiasy bezpośrednio po tekście, bez spacji, aby je rozdzielić: myFunc()
  3. Kropka lub strzałka między dwoma słowami: foo.bar = ptr->val
  4. Obecność nawiasów klamrowych, wsporników: while (true) { bar[i]; }
  5. Obecność składni „komentarza” (/ *, // itd.): /* multi-line comment */
  6. Niezbyt częste znaki / operatory: +, *, &, &&, |, ||, <, >, ==, !=, >=, <=, >>, <<, ::, __
  7. Uruchom zakreślacz składni na tekście. Jeśli w końcu podświetli jakiś wysoki procent, prawdopodobnie jest to kod.
  8. camel Umieść tekst we wpisie.
  9. zagnieżdżone nawiasy, nawiasy klamrowe i / lub nawiasy klamrowe.

Można śledzić, ile razy każdy z nich się pojawia, i można ich używać jako funkcji w algorytmie uczenia maszynowego, takiego jak perceptron , tak jak robi to SpamAssassin.


25
Wskazówki: 3 ma bardzo małą wagę, ponieważ kropka między słowami może być wynikiem literówki. 5 nie powinno pasować do adresów URL. W przypadku cyfry 6 znak „ampersand” jest również często używany poza kontekstem kodu, co może również zmniejszyć wagę tego znaku. Dokładnie sprawdź, czy wyróżnik działa, ponieważ może podświetlać tekst niekodowany, co czasami widzę w Notepad ++.
Tamara Wijsman,

8
ponownie. jako literówka - oznaczanie, że autor i tak powinien edytować, nie zaszkodzi.
user151019

4
dodatkowo mogą pomóc określone słowa kluczowe w wielu językach: WHILE, ELSE, IF, LOOP, BREAK itp.
JoséNunoFerreira

6
Dodaj „Zastosowanie $ przed słowami nieliczbowymi: $ var jest powszechny w Perlu i PHP (i Ruby?).”
PhiLho

4
Nie wykryjesz mojego SELECT DISTINCT name FROM people WHERE id IS NOT NULL.
Benoit

54

Byłbym ciekawy, jakie są średnie wskaźniki pisanego angielskiego z jednej strony i kodu z drugiej strony.

  • długość akapitów
  • długość linii
  • wielkość słów
  • używane znaki
  • stosunek znaków alfabetycznych, numerycznych i innych znaków symboli
  • liczba symboli na słowo
  • itp.

Może to samo może odróżnić już kod od reszty. Przynajmniej uważam, że kod, niezależnie od języka, w wielu przypadkach wykazywałby zauważalnie różne wskaźniki.

Dobra wiadomość jest taka: masz już mnóstwo danych, na których możesz budować statystyki.


Ok, wróciłem z pewnymi danymi na poparcie moich założeń. :-)

Zrobiłem szybki i brudny testu na swoim stanowisku i na pierwszym poście znalazłem na StackOverflow , z bardzo zaawansowane narzędzie: wc.

Oto, co miałem po uruchomieniu wcna części tekstowej i części kodowej tych dwóch przykładów:

Najpierw spójrzmy na część angielską :

  • Angielska część twojego postu (2635 znaków, 468 słów, 32 wiersze)
    • 5 znaków / słowo, 82 znaków / linia, 14 słów / linia
  • Angielska część drugiego postu (1499 znaków, 237 słów, 12 linii)
    • 6 znaków / słowo, 124 znaki / linia, 19 słów / linia

Całkiem podobne, nie sądzisz?

Teraz spójrzmy na część kodu !

  • Część kodu Twojego postu (174 znaki, 13 słów, 3 wiersze)
    • 13 znaków / słowo, 58 znaków / linia, 4 słowa / linia
  • Część kodowa drugiego postu (4181 znaków, 287 słów, 151 wierszy)
    • 14 znaków / słowo, 27 znaków / linia, 2 słowa / linia

Widzisz, jak różne są te wskaźniki, ale co ważniejsze, jak różnią się od wskaźników angielskich? A to tylko przy użyciu ograniczonego narzędzia. Jestem teraz pewien, że możesz uzyskać coś naprawdę dokładnego, mierząc więcej metryk (myślę w szczególności o statystykach znaków).

Mogę Haz Hazle?


6
Długość linii, szczególnie jeśli wykluczysz punkty wypunktowane i poszukasz klastrowanych linii o długości mniejszej niż określona, ​​zawierających określoną interpunkcję, wydaje się być dobrą miarą.
Jon Hopkins

To działałoby w przypadku bloków kodu, ale o wiele trudniej było szukać wbudowanego cdde. Nie jestem jednak pewien, jak bardzo to ma znaczenie - większym problemem są i tak duże bloki niesformatowanego kodu.
cHao

3
Żadnych ciasteczek. Link do twojego posta to 404.
james.garriss

@ james.garriss: Internet ukradł mój słoik z ciasteczkami. :( Dziękuję za powiadomienie.
Julien Guertault

23

Zazwyczaj łańcuchy Markowa są używane do generowania tekstu, ale mogą być również używane do przewidywania podobieństwa tekstu (zgodnie z CE Shannon 1950 ) do wyuczonego modelu. Polecam wiele łańcuchów Markowa.

Dla każdego rozpowszechnionego języka wytrenuj łańcuch Markowa na dużej, reprezentatywnej próbce kodu w tym języku. Następnie dla postu przepełnienia stosu, dla którego chcesz wykryć kod, wykonaj następujące czynności dla każdego łańcucha:

  • Zapętlaj linie w poście.
    • Zadeklaruj dwie zmienne: RZECZYWISTY = 1.0 i NAJWYŻSZY = 1.0
    • Pętlę przez każdy znak w linii.
      • Dla każdego znaku znajdź prawdopodobieństwo w łańcuchu Markowa, że ​​bieżący znak jest tym, który występuje po poprzednich N znakach. Ustaw ACTUAL = ACTUAL * PROB 1 . Jeśli bieżący znak nie jest obecny w łańcuchu, użyj małej wartości dla PROB 1 , na przykład 0,000001.
      • Teraz znajdź postać, która najprawdopodobniej (tj. Najwyższe prawdopodobieństwo) podąży za poprzednimi N znakami. Ustaw NAJWYŻSZA = NAJWYŻSZA * Sonda 2 .
      • Oczywiście, PROB 2 > = PROB 1

Dla każdej linii powinieneś mieć wartość RZECZYWISTĄ i NAJWYŻSZĄ. Podziel RZECZYWISTY przez NAJWYŻSZY. To da ci ocenę sprawności, czy dana linia jest kodem źródłowym. To by skojarzyło liczbę z każdą linią w podanym przykładzie:

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

Na koniec musisz wybrać próg, aby określić, kiedy w kodzie jest kod. Może to być po prostu liczba wybrana przez obserwację, która daje wysoką wydajność. Może również uwzględniać liczbę linii z wysokim wynikiem.

Trening

Aby trenować, zamów dużą reprezentatywną próbkę kodu w języku. Napisz program, który zapętli tekst kodu i powiąże każdy N-gram w pliku (zakres dla N powinien zostać sparametryzowany) z częstotliwością statystyczną następnego znaku. To da wiele możliwych stanów znaków następujących po bigramie, każdy związany z prawdopodobieństwem. Na przykład bigram „()” może mieć następujące prawdopodobieństwo postaci:

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

Pierwszy należy odczytać, na przykład jako „Prawdopodobieństwo, że średnik podąży za pustym nawiasiem, wynosi 0,5”.

Na trening polecam N-gramów od dwóch do pięciu. Wcześniej, kiedy przeprowadziłem badania na ten temat , stwierdziliśmy, że N-gram w rozmiarach od drugiego do piątego działał dobrze w języku angielskim. Ponieważ znaczna część kodu źródłowego jest podobna do angielskiej, sugerowałbym rozpoczęcie od tego zakresu, a następnie dostosowanie w celu znalezienia optymalnych wartości parametrów w miarę znajdowania, co działa.

Zastrzeżenie: na model będą miały wpływ identyfikatory, nazwy metod, białe znaki itp. Można jednak dostroić trening, aby pominąć niektóre cechy próbki treningowej. Na przykład możesz zwinąć wszystkie niepotrzebne białe znaki. Obecność białych znaków na wejściu (słupek przepełnienia stosu) można również zignorować. Można również zignorować wielkość liter, która byłaby bardziej odporna w obliczu różnych konwencji nazewnictwa identyfikatorów.

Podczas moich badań stwierdziliśmy, że nasze metody sprawdzają się zarówno w języku hiszpańskim, jak i angielskim. Nie rozumiem, dlaczego to również nie działałoby dobrze w przypadku kodu źródłowego. Kod źródłowy jest jeszcze bardziej uporządkowany i przewidywalny niż ludzki język.


2
Jedynym problemem, który przewiduję, jest to, że prawdopodobieństwo będzie znacznie mniejsze niż w twoim przykładzie zabawki. Biorąc pod uwagę niestabilność numeryczną, oznacza to, że wkrótce wszystkie prawdopodobieństwa wynoszą 0. Jednak użycie logarytmowych szans rozwiązuje to. Ponadto użyłbym większych tokenów (tj. Nie znaków, ale słów / interpunkcji).
Konrad Rudolph

2
@Konrad: tutaj nie chodzi o testowanie prawdopodobieństw bezwzględnych: chodzi o sprawdzenie prawdopodobieństw względnych. W przypadku każdego wiersza tekst tego wiersza może zostać wygenerowany przez model języka angielskiego lub model języka kodu.
Ken Bloom

5
Możesz trenować ten model na istniejących postach SO (szczególnie dlatego, że może być konieczne uwzględnienie składni Markdown). Jeśli założysz, że większość postów jest poprawnie sformatowana (lub przeglądasz dużą liczbę postów, rzędu dziesiątek tysięcy, aby usunąć posty, które nie są poprawnie sformatowane), to zakładasz, że to, co nie jest sformatowane kodem, to tekst w języku angielskim , a formatowanym kodem jest kod, który można trenować na podstawie rzeczywistych odpowiedzi SO.
Ken Bloom

1
Samouczek na temat tego, jak to zrobić (za pomocą LingPipe w Javie) jest dostępny na stronie internetowej LingPipe . Na końcu samouczka znajduje się wiele artykułów na temat technik rozwiązania tego problemu. Sugeruję je przeczytać.
Ken Bloom

1
Interesujące jest to, że najnowocześniejsze rozwiązanie ma tylko bardzo małą liczbę głosów, a stawki są znacznie niższe niż wszystkie te rozwiązania ad hoc, które, co prawda, mogą być wystarczająco dobre, ale w dużej mierze polegają na specjalnej obudowie i są z natury podatny na nadmierne dopasowanie.
Konrad Rudolph

13

Czy mogę zasugerować zupełnie inne podejście? W SO jedynym dozwolonym językiem ludzkim jest angielski, więc wszystko, co nie jest angielskim, ma 99,9% szans na bycie fragmentem kodu .

Tak więc moim rozwiązaniem byłoby: użyć jednego z wielu sprawdzających język angielski (upewnij się, że sygnalizują one - oprócz błędów pisowni - błędy składniowe, takie jak podwójne kropki, lub symbole niejęzykowe, takie jak #lub ~). Następnie każdy wiersz / akapit, który generuje dużą liczbę błędów i ostrzeżeń, powinien wywołać „czy ten kod?” pytanie.

To podejście można również dostosować do tych stron StackExchange, które używają innych języków niż angielski.

Just my 2 ¢ ...


16
Problem polega na tym, że wiele z nadchodzących pytań nie jest po angielsku (chociaż są podobne).
Brendan Long

3
@Brendan - Dodano zaletę tej propozycji: podkreśl (lub wyróżnij) błędy w części postu, która prawdopodobnie powinna być w języku angielskim, i pomóż pisarzowi pisać ... po angielsku! ;)
Mac

1
Jestem Holendrem i wszystko, co koduję, jest w języku angielskim, komentarze nie są (w zależności od projektu). Zatem kodowanie w języku innym niż angielski nie wystarczy. To lub masz na myśli, że zepsuty angielski musi być kodem.
Ivo Limmen

@Ivo - Mój komentarz był żartobliwie adresowany do zepsutego angielskiego wydania! ;) Powiedziałbym jednak, że z moją propozycją komentarze w innym języku będą działały dobrze ... Komentarze blokowe OTOH w języku angielskim nie wywołują „czy ten kod?” pytanie, ale to w porządku, ponieważ kod, dla którego napisano komentarz, już go wywołałby ...
Mac

11

Prawdopodobnie otrzymam za to kilka głosów, ale myślę, że podchodzisz do tego z niewłaściwego punktu widzenia.

Ta linia dała mi:

ludzie muszą wejść i ręcznie sformatować kod dla osób, które w jakiś sposób nie są w stanie tego zrozumieć

IMO to stanowisko jest trochę aroganckie. Znajduję to dużo w projektowaniu oprogramowania, w którym programiści i projektanci denerwują się użytkownikami, którzy nie mogą dowiedzieć się, jak prawidłowo korzystać z oprogramowania, gdy problemem nie jest użytkownik, ale samo oprogramowanie - lub przynajmniej interfejs użytkownika.

Podstawową przyczyną tego problemu nie jest użytkownik, ale fakt, że nie jest dla niego oczywiste, że mogą to zrobić.

Co powiesz na zmianę w interfejsie użytkownika, aby uczynić to bardziej oczywistym? Na pewno będzie to:

  1. bardziej oczywiste dla nowych użytkowników, co dokładnie muszą zrobić
  2. łatwiej jest budować niż pisać skomplikowane algorytmy w celu wykrycia logiki kodu w wielu językach

Przykład:

wprowadź opis zdjęcia tutaj


26
Właściwie to IMO wymusza słabe pytania, takie jak: „Mam problem, pomóżcie mi, kod jest poniżej” - dość rzadko kod należy oddzielić od pytania. Najlepsze pytania brzmią następująco: „Chcę to osiągnąć i napisałem te dwa wiersze kodu, ale efekt jest następujący, w czym problem” - jest bardzo mało kodu mocno przeplatanego prostym językiem.
sharptooth

4
Twoja obserwacja korzeń jest poprawna, ale twoja diagnoza jest nadal źle: w rzeczywistości, Jeff jest stara się poprawić interfejs użytkownika za pomocą tego podejścia. Co więcej, obecny interfejs użytkownika przeszedł już kilka cykli i chociaż nie wątpię, że można go poprawić (drastycznie), wątpię, czy pomogłoby to leniwym idiotom. Proponowane rozwiązanie również nie będzie. @sharptooth ma to objęte.
Konrad Rudolph

2
Dałbym +1 za przemyślenie, ale nie zgadzam się z konkretną sugestią, ponieważ opublikowanie „kodu pomocniczego” wymusza przepływ pytań, który może być nienaturalny. Nigdy nie po prostu rzuciłem kod na dole mojego pytania. Prawie zawsze publikuję wprowadzenie, przykładowy kod, a następnie pytanie. Jeśli zaakceptujesz tę przesłankę, że kod wbudowany jest niezbędny, wówczas wymagany jest pewien rodzaj formatowania - formatowanie, które musi wprowadzić użytkownik lub zalecić system. Właśnie o to pyta Jeff.
Nicole

1
@Konrad: Oprócz mojego powyższego komentarza i w odpowiedzi na twoje, nie wierzę, że Jeff ulepsza interfejs użytkownika, podążając tą ścieżką, ale po prostu lecząc objawy podstawowego problemu. Jeśli interfejs użytkownika został ulepszony, aby nie można było popełnić błędu, rozwiązanie ostrzegania użytkownika nie byłoby konieczne. Nie mam złudzeń, że mój przykład jest ostatecznym rozwiązaniem, ale należy zastanowić się nad pytaniem „czy przedstawiamy to w najlepszy możliwy sposób?”.
matt_asbury

1
Proste zdanie proszę oznaczyć kod za pomocą {}przycisku wokół pola tekstowego.
Paŭlo Ebermann

11

Pseudo kod stanowiłby prawdziwe wyzwanie, ponieważ cały język programowania zależy od znaków specjalnych, takich jak „[]”, „;”, „()” itp. Wystarczy policzyć występowanie tych znaków specjalnych. Podobnie jak w przypadku wykrycia pliku binarnego (ponad 5% próbki zawiera wartość bajtu 0).


Poprawiłbym to tak bardzo, jak grupy takich specjalnych znaków, jak [] (); {} =. Każdy wiersz zawierający więcej niż 2-3 z tych grup jest wierszem kodu.
Honza

... a także poszukaj typowych ciągów w najpopularniejszych językach, np. „= someord ();” w przypadku większości nawiasów klamrowych składnia podobna do XML, taka jak „<something>” i „<ab: cde>”, oraz inne popularne ciągi znaków w innych językach. Wierzę, że jakaś tabela przeglądowa o wspólnej składni byłaby dobrym rozwiązaniem, ponieważ możesz ją rozwinąć, gdy znajdziesz nowe języki do zaimplementowania.
Arve Systad

Prawdopodobnie powinieneś upuścić pseudo kod. Niektórzy lubią pisać w języku C, ale inni używają zwykłego angielskiego z czymś, co wygląda bliżej VB6
James P.

4

Myślę, że być może będziesz musiał skierować to tylko na określone języki, ogólnie problem ten jest prawdopodobnie trudny do rozwiązania, ponieważ możesz uzyskać języki bardzo podobne do angielskiego (np. Inform7 ). ale na szczęście te najczęściej używane można dość łatwo pokryć.

Moim pierwszym cięciem byłoby poszukiwanie sekwencji „; \ n”, która dałaby ci dobre dopasowanie do C, C ++, Java, C # i każdego innego języka, który używa podobnej składni i jest naprawdę prosty. Jest również mniej prawdopodobne, że będzie używany w języku angielskim niż; bez nowej linii


plus może obfitość kręconych aparatów ortodontycznych; p
Marc Gravell

1
Jak mówi Jeff w swoim poście, prawdopodobnie będą kierować reklamy tylko na główne języki. W każdym razie podejrzewam, że nowi użytkownicy (dla których ta funkcja jest przeznaczona) będą częściej publikować C # lub JavaScript niż, powiedzmy, INTERCAL ;-)
Ben

Tak, ale nie działałoby to z językiem programowania BRAINFUCK lub BLANK. ;-)
Ivo Limmen,

4

Ktoś wspomniał, że patrzy na tagi, a następnie szuka do tego składni, ale zostało to zestrzelone, ponieważ jest to skierowane do nowych użytkowników.

Możliwym lepszym rozwiązaniem byłoby poszukiwanie nazw języków w treści pytania, a następnie zastosowanie tej samej strategii. Jeśli wspomnę o „Javascript”, „Java” lub „C #”, prawdopodobnie są o to chodzi w pytaniu, a kod w pytaniu prawdopodobnie będzie w tym języku.


Zwłaszcza jeśli tytuł brzmi „Vb c # .net kropka netto, pomóż mi!”
NickAldwin

1

Najpierw uruchom go przez sprawdzanie pisowni, znajdzie bardzo mało poprawnych angielskich słów, jednak powinno być wiele słów, które sprawdzanie pisowni sugeruje podzielić.

Następnie są znaki interpunkcyjne / specjalne, które nie są typowe dla zwykłego angielskiego, typowe dla kodu:

  • something(); po prostu nie może być prostym językiem angielskim;
  • $somethinggdzie somethingnie wszystkie są liczbami;
  • -> między słowami bez spacji;
  • . między słowami bez spacji;

Oczywiście, aby działał dobrze, możesz chcieć mieć klasyfikator bayesowski zbudowany na tych cechach.


1
Wykrywanie nieciętej linii zawierającej (); byłby dobrym powodem do zasugerowania przesłania.

Który moduł sprawdzania pisowni nie zadławi się przed wklejeniem kodu?
Tim Post

W przypadku niektórych wiadomości napisanych przez rodzimych pisarzy angielskich
moduł

@Ph: te pytania / odpowiedzi i tak nie są akceptowane.
vartec

1

istnieje kilka zestawów języków o podobnej składni. na kilka języków wpłynęło kilka języków, więc języki [AMPL, AWK, csh, C ++, C--, C #, Objective-C, BitC, D, Go, Java, JavaScript, Limbo, LPC, Perl, PHP, Pike, Processing [były pod wpływem C, więc jeśli wykryjesz C, prawdopodobnie wykryjesz wszystkie te języki. więc musisz tylko napisać prosty wzorzec wykrywania tych zestawów językowych.

podzieliłbym również tekst na bloki, ponieważ większość kodu zostanie podzielona na dwie nowe linie lub podobne z innych bloków tekstu w poście.

można to łatwo zrobić za pomocą javascript (superkompletna niekompletna próbka dla rodziny 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 + "]");
   }
}

0

Po prostu policz słowa / znaki interpunkcyjne dla każdej linii. Angielski będzie miał zwykle 4 lub więcej, kod mniej niż 2.

Powyższy akapit zawiera na przykład 18 słów i 4 znaki interpunkcyjne. Ten akapit ma 19 słów i 4 znaki interpunkcyjne, więc w granicach oczekiwań.

Oczywiście trzeba by to sprawdzić pod kątem pytań osób słabo znających angielski dla początkujących, i być może w takich przypadkach statystyki są wypaczone.

Oczekuję, że [nie-białe znaki]. [Białe znaki lub nowa linia] jest bardzo rzadkie w kodzie, ale jest powszechne w języku angielskim, więc można to liczyć jako słowa, a nie interpunkcję.

Myślę, że największym problemem będzie kod wewnętrzny, w którym ktoś zadaje takie pytanie:

Jeśli mówię za (i = 0; i> 100; i ++) {} co to oznacza?

To jest kod i angielski, i powinny być oznaczone jako tyknięcia:

Jeśli powiem, for (i=0; i>100; i++) {}co to znaczy?


0

Myślę, że najpierw powinieneś dokonać rozróżnienia między (wystarczająco) sformatowanym kodem, który musi być tak naprawdę oznaczony jako taki, a (zbyt) źle sformatowanym kodem, który i tak wymaga ręcznego formatowania.

Sformatowany kod ma linie nieciągłości i wcięcia. To znaczy: jeśli linia jest poprzedzona pojedynczą linią przerwania, masz dobrego kandydata. Jeśli oprócz tego ma wiodące białe znaki, masz bardzo dobrego kandydata.

Normalny tekst używa dwóch linii nieciągłości lub dwóch spacji i linii nieciągłości do formatowania, więc istnieje wyraźne kryterium rozróżnienia.

W kodzie LISP nie znajdziesz średników, w kodzie Ruby możesz nie znaleźć nawiasów, w pseudo-kodzie możesz wcale nie znaleźć wiele. Ale w każdym (nie-ezoterycznym) języku znajdziesz porządny kod do sformatowania za pomocą linii nieciągłości i wcięć. Nie ma nic tak uniwersalnego. Ponieważ w końcowym kodzie jest napisany do odczytu przez ludzi.

Najpierw poszukaj potencjalnych linii kodu . Ponadto wiersze kodu zwykle występują w grupach. Jeśli masz taki, istnieje duża szansa, że ​​ten powyżej lub poniżej jest również wierszem kodu.

Po wyodrębnieniu potencjalnych wierszy kodu możesz je sprawdzić według kryteriów kwantyfikowalnych i wybrać próg :

  • częstotliwość znaków innych niż słowa
  • częstotliwość identyfikatorów: bardzo krótkie lub bardzo długie słowa w stylu CamelCase lub under_score
  • powtórzenie nietypowych słów

Ponadto, teraz, gdy są programiści i cs, zakres stackoverflow jest wyraźnie zawężony. Można rozważyć oznaczenie wszystkich znaczników językowych jako języków. Podczas publikowania zostaniesz poproszony o wybranie co najmniej jednego tagu językowego, wybranie language-agnostictagu lub wyraźne pominięcie go.

W pierwszym przypadku wiesz, jakich języków szukać, w drugim przypadku możesz poszukać pseudokodu, aw ostatnim przypadku prawdopodobnie nie będzie żadnego kodu, ponieważ jest to pytanie związane z jakąś technologią lub ramy lub takie.


0

Możesz utworzyć parser dla każdego języka, który chcesz wykryć (definicje języka dla ANTLR są zwykle łatwe do znalezienia), a następnie uruchomić każdą linię pytania w każdym parserze. Jeśli którykolwiek wiersz jest poprawnie analizowany, prawdopodobnie masz kod.

Problem polega na tym, że niektóre zdania w języku angielskim (w języku naturalnym) mogą być analizowane jako kod, więc możesz chcieć dołączyć także inne pomysły lub możesz ograniczyć pozytywne wyniki tylko wtedy, gdy więcej niż jeden lub dwa kolejne wiersze poprawnie przeanalizują z parser tego samego języka.

Innym potencjalnym problemem jest to, że prawdopodobnie nie odbierze pseudokodu, ale może być OK.


Często ludzie mają błędy składniowe w kodzie (i pytają o to).
Paŭlo Ebermann

0

To, co może być najbardziej przyszłościowe i wymagać będzie najmniejszej ręcznej regulacji na dłuższą metę, ponieważ inne języki (które wyglądają nieco inaczej niż obecnie używane języki programowania) stają się bardziej popularne, a obecnie używane języki stają się mniej popularne, to robić coś w rodzaju tego, co robi Tłumacz Google (patrz akapit zatytułowany „Jak to działa?”) zamiast szukać pewnych rzeczy, takich jak ab i a () itp.

Innymi słowy, zamiast ręcznie wymyślić wzorce znalezione w kodzie, którego można szukać, komputer może sam to zrozumieć . Można to zrobić, mając

  1. dużo kodu w wielu różnych językach programowania

    • Sugestia: automatycznie pobieraj próbki kodu z internetowych repozytoriów kodu źródłowego, takich jak Google Code lub Github, a nawet z rzeczy w Stackoverflow już oznaczonych jako kod

    • Uwaga: dobrym pomysłem może być przeanalizowanie komentarzy do kodu

  2. dużo angielskiego tekstu zaczerpniętego z artykułów w Internecie

    • chociaż nie z artykułów o programowaniu (w przeciwnym razie mogą mieć kod i pomieszać system :-))

i posiadanie pewnego rodzaju algorytmu automatycznie znajduje wzorce w kodzie, które nie są w języku angielskim, i odwrotnie, i używając tych wzorców do wykrycia, co jest kodem, a co nie kodem, uruchamiając algorytm na postach.

(Nie jestem jednak pewien, jak taki algorytm działałby. Inne odpowiedzi na bieżące pytanie mogą zawierać przydatne informacje.)

Następnie system może ponownie skanować kod co jakiś czas, aby uwzględnić zmiany w sposobie wyświetlania kodu w tym momencie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.