Metin kodunu güvenilir bir şekilde algılamak için basit bir yöntem?


142

GMail, eki olabileceğini düşündüğü bir e-posta göndermeyi denerseniz sizi uyaracağı bu özelliğe sahiptir .

Dosya eklemek mi istediniz?

GMail see the attached, e-postadaki dizgiyi tespit ettiğinden , ancak gerçek bir ek bulunmadığından, Gönder düğmesine tıkladığımda beni Tamam / İptal iletişim kutusuyla uyarır.

Yığın Taşması ile ilgili bir sorunumuz var. Yani, kullanıcı böyle bir yazı girdiğinde :

benim sorunum veritabanını değiştirmem gerek ama yaratmam 
yeni bir bağlantı. örnek:

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

Bu kullanıcı kodunu kod olarak biçimlendirmedi !

Yani, Markdown başına 4 boşluk girmediler ya da kendileri için bunu yapan kod düğmesini (ya da klavye kısayolunu ctrl+ k) kullandılar.

Bu nedenle, sistemimiz insanların girmesi gereken birçok düzenlemeyi kabul ediyor ve bunu bir şekilde anlayamayan insanlar için kodu manuel olarak formatlıyor. Bu, çok fazla zahmete neden olur . Editör yardımını birkaç kez geliştirdik, ancak kullanıcının evine gitmekten ve klavyelerinde doğru düğmelere basmaktan vazgeçtiklerinde, sonra ne yapacağımızı göremiyoruz.

Bu yüzden bir Google GMail tarzı uyarısı düşünüyoruz:

Kod göndermek mi istedin?

Kod gibi göründüğünü düşündüğümüz şeyler yazdınız, ancak araç çubuğu kodu düğmesini veya ctrl+ kkod biçimlendirme komutunu kullanarak 4 boşluk girerek kod olarak biçimlendirmediniz.

Ancak, bu uyarının sunulması , bir soruda biçimlendirilmemiş kod olduğunu düşündüğümüz şeyin varlığını tespit etmemizi gerektirir . Bunu yapmanın basit, yarı güvenilir bir yolu nedir?

  • İşaretleme Başına , kod her zaman 4 boşlukla veya backticks içinde girintili olduğundan, doğru biçimlendirilmiş herhangi bir şey hemen kontrolten atılabilir.
  • Bu sadece bir uyarıdır ve yalnızca ilk sorularını soran (veya ilk cevaplarını veren) düşük itibarlı kullanıcılar için geçerlidir, bu nedenle bazı yanlış pozitifler yaklaşık% 5 ya da daha az olduğu sürece tamamdır.
  • Yığın Taşması ile ilgili sorular, herhangi bir dilde olabilir, ancak çekimizi "büyük on" dille sınırlamak için gerçekçi bir şekilde sınırlayabiliriz. C #, Java, PHP, JavaScript, Objective-C, C, C ++, Python, Ruby olacak etiket sayfası başına.
  • Kullanım yığın taşması Creative Commons veri dökümü potansiyel çözüm denetlemek (ya da sadece bir kaç soru almak ilk 10 etiketleri Yığın taşması) ve öyle bakın.
  • Sahte kod iyi, ancak fazladan dost olmak istiyorsanız c # kullanıyoruz.
  • Ne kadar basitse o kadar iyi (çalıştığı sürece). ÖPMEK! Çözümünüz, 10 farklı derleyicideki postaları veya bir bayes dili çıkarım motorunu elle eğitmek için bir insan ordusunu derlemeye çalışmamızı gerektiriyorsa, bu tam olarak aklımızdaki gibi değildi.

34
Girinti yoksa, sadece uyarıyı her zaman görüntülerseniz,% 5 hata sınırının çok altında olacağınızı düşünüyorum. Bu sadece yarısı şaka demek.
Konrad Rudolph

59
@Konrad Bu mesaj şu şekilde olsa daha iyi sonuç verir: 'Sorunuz ya başkalarının anlamasına yardımcı olacak kod örneklerinden yoksun ya da doğru şekilde girmeyi unuttum.' Bu, tüm vakaların% 99'unu kapsamalıdır.
thorsten müller

3
Bu iyi bir soru ama cevabı olmadığını düşünüyorum. Bana aptal geçirmez bir sistem gösterirsin ve sana daha iyi bir aptal gösteririm. Bu problem KOD tarafından ele alınabilse bile, belki de yapmamalı mı? Bu cahil insanlar, benim gibi uygun sorular soran ve doğru cevaplara katkıda bulunanlar için bu siteyi ÇALIŞTIRAN YANITLI BİR SORU sormaktan rahatsız olamazlar.
maple_shaft

2
Gördüğüm yaygın bir kalıp, kendi içinde uygun bir şekilde girintili bir kod bloğudur, ancak ilk ve son satırların (genellikle sadece iki, bazen birden fazla işlev gösterdiğinde daha fazla) kod olarak etiketlenmediği yerdir. Bu muhtemelen de tespit edilmelidir.
3Doubloons

3
Bir yandan notta, GMail onay metni oldukça kafa karıştırıcıdır. İlk soruya cevabınız 'evet' ise, ikinci soruya cevabınız 'hayır' ...
pimvdb

Yanıtlar:


147

Uygun bir çözüm muhtemelen öğrenilmiş / istatistiksel bir model olacaktır, ancak işte eğlenceli fikirler:

  1. Bir satırın sonundaki noktalı virgül . Bu tek başına bir sürü dili yakalar.
  2. Ayırmak için boşluğa sahip olmayan metni doğrudan izleyen parantez: myFunc()
  3. İki kelime arasında bir nokta veya ok: foo.bar = ptr->val
  4. Kıvrımlı ayraçların varlığı, parantez: while (true) { bar[i]; }
  5. "Comment" sözdiziminin varlığı (/ *, //, etc): /* multi-line comment */
  6. Yaygın olmayan karakterler / operatörler: +, *, &, &&, |, ||, <, >, ==, !=, >=, <=, >>, <<, ::, __
  7. Metin üzerindeki sözdizimi vurgulayıcınızı çalıştırın. Bazı yüksek yüzdesini vurgulayarak sona ererse, muhtemelen kodudur.
  8. yayındaki camelCase metni.
  9. iç içe parantezler, kaşlı ayraçlar ve / veya parantezler.

Biri bunların her birinin ortaya çıkma sayısını takip edebilir ve bunlar SpamAssassin'in yaptığı gibi, algılayıcı gibi bir makine-öğrenme algoritmasında özellik olarak kullanılabilir .


25
İpuçları: 3, çok düşük bir ağırlığa sahiptir, çünkü kelimeler arasındaki bir nokta bir yazım hatası olabilir. 5, URL’lerle eşleşmemelidir. 6 için ve işareti, kod bağlamı dışında da sıkça kullanılır; bu, bu karaktere daha az ağırlık verebilir. Vurgulayıcının işe yarayıp yaramadığını iki kez kontrol edin, çünkü bazen Notepad ++ 'da gördüğüm gibi kod dışı metni vurgulayabilir.
Tamara Wijsman

8
Budur . Bir yazım hatası olarak - yazar yine de düzenlemesi gerektiğinin işaretlemesinde hiçbir zararı olmaz.
kullanici151019

4
ayrıca, birçok dilin yardımcı olabileceği belirli anahtar kelimeler: WHILE, ELSE, IF, LOOP, BREAK, vb.
JoséNunoFerreira

6
"Sayısal olmayan sözcüklerden önce $ kullanımı: $ var Perl ve PHP (ve Ruby?) 'De yaygındır."
PhiLho

4
Algılamayacaksın SELECT DISTINCT name FROM people WHERE id IS NOT NULL.
Benoit

54

Bir tarafta yazılı İngilizcenin ortalama metriklerinin ne olduğunu ve diğer tarafta kodun ne olduğunu görmek isterim.

  • paragrafların uzunluğu
  • satır uzunluğu
  • kelimelerin boyutu
  • kullanılan karakter
  • Alfabetik, sayısal ve diğer sembol karakterleri arasındaki oran
  • kelime başına sembol sayısı
  • vb.

Belki de tek başına zaten kod ve geri kalanı arasında ayrımcılık olabilir. En azından, dilden bağımsız olarak, kodun birçok durumda fark edilir derecede farklı ölçümler göstereceğine inanıyorum.

İyi haber şu: istatistiklerinizi oluşturmak için zaten yeterli miktarda veriye sahipsiniz.


Tamam Varsayımlarımı desteklemek için bazı verilerle geri döndüm. :-)

Ben kendi yayında bir hızlı ve kirli test yaptım ve üzerinde birinci mesaja Ben StackOverflow'daki buldum oldukça gelişmiş araç ile,: wc.

İşte wcbu iki örnekte, metin kısmında ve kod kısmında çalıştıktan sonra yaşadıklarım :

İlk önce İngilizce kısmına bakalım :

  • Yayınınızın İngilizce kısmı (2635 karakter, 468 kelime, 32 satır)
    • 5 karakter / kelime, 82 karakter / çizgi, 14 kelime / çizgi
  • Diğer yazının İngilizce kısmı (1499 karakter, 237 kelime, 12 satır)
    • 6 karakter / kelime, 124 karakter / çizgi, 19 kelime / çizgi

Oldukça benzer değil mi sence?

Şimdi kod kısmına bir göz atalım !

  • Yazınızın kod kısmı (174 karakter, 13 kelime, 3 satır)
    • 13 karakter / kelime, 58 karakter / çizgi, 4 kelime / çizgi
  • Diğer yazının kod kısmı (4181 karakter, 287 kelime, 151 satır)
    • 14 karakter / kelime, 27 karakter / çizgi, 2 kelime / çizgi

Bu metriklerin ne kadar farklı olmadığını görün, ama daha önemlisi, İngilizce metriklerinden ne kadar farklı olduklarını görün. Ve bu sadece sınırlı bir araç kullanıyor. Artık daha fazla ölçüm ölçerek gerçekten doğru bir şey alabileceğinize eminim (özellikle chars istatistiklerini düşünüyorum).

Kurabiyeyi yapabilir miyim?


6
Satır uzunluğu, özellikle madde noktalarını hariç tutarsanız ve belirli noktalama işaretlerini içeren belirli bir uzunluktan daha az kümelenmiş satırlar ararsanız, iyi bir ölçü gibi görünebilir.
Jon Hopkins

Bu kod blokları için işe yarar, ancak satır içi cdde'yi aramak çok daha zor görünüyordu. Ne kadar önemli olduğu belli değil - daha büyük sorun zaten biçimlenmemiş kodun büyük blokları.
cHao

3
Kurabiye yok.
Gönderinizdeki

@ james.garriss: İnternet benim çerez kavanozumu çaldı. :( Ancak duyuru için teşekkür ederiz.
Julien Guertault

23

Tipik olarak, Markov zincirleri metin üretmek için kullanılır, ancak metnin ( CE Shannon 1950'ye göre ) eğitimli bir modele benzerliğini tahmin etmek için de kullanılabilirler . Birden fazla Markov zinciri öneririm.

Her yaygın dil için, dilde büyük, temsili bir kod örneği üzerine bir Markov zinciri eğitin. Ardından, kodu algılamak istediğiniz Yığın Taşması postası için, her bir zincir için aşağıdakileri yapın:

  • Gönderideki çizgiler arasında dolaşın.
    • İki değişken bildir: ACTUAL = 1.0 ve HIGHEST = 1.0
    • Satırdaki her karakter arasında dolaşın.
      • Her karakter için, Markov zincirindeki mevcut karakterin önceki N karakterini takip eden karakter olma olasılığını bulun. ACTUAL = ACTUAL * PROB 1'i ayarlayın . Mevcut karakter zincirde mevcut değilse, o zaman 0.000001 gibi, PROB 1 için küçük bir değer kullanın .
      • Şimdi, önceki N karakterlerini takip etmesi en muhtemel olan karakteri (yani en yüksek olasılık) bulun. YÜKSEK ayar = YÜKSEK * SORUN 2 .
      • Açıkçası, PROB 2 > = PROB 1

Her satır için GERÇEK ve YÜKSEK bir değere sahip olmalısınız. GERÇEKTEN GERÇEĞE bölün. Bu, belirli bir satırın kaynak kodu olup olmadığı konusundaki zindelik puanını verecektir. Bu, verdiğiniz örnekteki satırların her biri ile bir sayı ilişkilendirir:

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

Son olarak, gönderimde kod olup olmadığını belirlemek için bir eşik seçmeniz gerekir. Bu, sadece yüksek performans sağlayan gözlemle seçilen bir sayı olabilir. Ayrıca yüksek skorlu satır sayısını da dikkate alabilir.

Eğitim

Eğitmek, dilde büyük, temsili bir kod örneği almak. Kod metni üzerinde dolaşmak için bir program yazın ve dosyadaki her N-gramını (N için aralık parametreleştirilmelidir) sonraki karakterin istatistiksel frekansıyla ilişkilendirin. Bu, her biri bir olasılık ile ilişkili olan bigramı takip eden birçok olası karakter durumu üretecektir. Örneğin, "()" bigramının bazı aşağıdaki karakter olasılıkları olabilir:

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

Birincisi, örneğin "Noktalı virgülün boş bir parantetik izlemesi olasılığı 0,5" olabilir.

Eğitim için, ikiden beşe kadar olan N-gram büyüklüğünü öneririm. Bu konuda biraz araştırma yaptığımda, N-gram büyüklüğünün iki ila beşinin İngilizce için iyi çalıştığını gördük. Kaynak kodunun çoğu İngilizce gibi olduğundan, bu aralıktan başlamanızı ve sonra neyin işe yaradığını bulduğunuzda en uygun parametre değerlerini bulmak için ayarlamayı öneririm.

Bir uyarı: Model tanımlayıcılardan, yöntem adlarından, boşluktan vb. Etkilenir. Ancak, eğitim örneğinin belirli özelliklerini atlamak için eğitimi ayarlayabilirsiniz. Örneğin, gereksiz tüm boşlukları daraltabilirsiniz. Girişteki boşlukların varlığı (Yığın Taşması direği) de göz ardı edilebilir. Ayrıca, farklı tanımlayıcı adlandırma kuralları karşısında daha esnek olacak olan alfabetik durumu da görmezden gelebilirsiniz.

Araştırmam sırasında , yöntemlerimizin İngilizcenin yanı sıra İspanyolca için de iyi çalıştığını gördük. Bunun neden kaynak kodu için iyi çalışmadığını anlamıyorum. Kaynak kodu, insan dilden bile daha yapılandırılmış ve tahmin edilebilir.


2
Tahmin ettiğim tek sorun, olasılıkların oyuncak örneğinizden çok daha küçük olacağı yönünde . Sayısal dengesizlik göz önüne alındığında, bu kısa sürede tüm olasılıkların 0 olduğu anlamına gelir. Günlük oranlarını kullanmak bunu çözer. Dahası, daha büyük belirteçler kullanırdım (yani karakterler değil, kelimeler / noktalama işaretleri).
Konrad Rudolph

2
@Konrad: Buradaki fikir mutlak olasılıkları test etmek değil: göreceli olasılıkları test etmek. Her satır için, bu satırın metni bir İngiliz dili modeli veya bir kod dili modeli tarafından oluşturulmuş olabilir.
Ken Bloom,

5
Bu modeli mevcut SO gönderilerinde eğitebilirsiniz (özellikle Markdown sözdizimini hesaba katmanız gerekebileceğinden). Çoğu gönderinin doğru biçimlendirildiğini varsayıyorsanız (veya doğru biçimlendirilmemiş iletileri kaldırmak için on binlerce sırasına göre çok sayıda gönderi seçersiniz), o zaman kod biçimlendirilmemiş öğelerin İngilizce metin olduğunu kabul edersiniz. ve kod biçimlendirilmiş olan şeyler koddur, gerçek SO yanıtlarından eğitebilirsiniz.
Ken Bloom,

1
Bunun nasıl yapılacağı hakkında bir öğretici (Java'da LingPipe kullanarak) LingPipe web sitesinden edinilebilir . Eğitimin sonunda, bu sorunun üstesinden gelme teknikleri hakkında çok sayıda makale var. Onları okumanı öneririm.
Ken Bloom,

1
Son teknoloji ürünü çözümün sadece çok düşük bir oy sayısına sahip olduğunu ve kuşkusuz, yeterince iyi ancak özel kaplamaya çok fazla güven duyan tüm özel çözümlerden çok daha az oranda olduğunu görmek ilginçtir. abartılı eğilimli.
Konrad Rudolph

13

Çok farklı bir yaklaşım önerebilir miyim? SO'da izin verilen tek insan dili İngilizce'dir, bu yüzden İngilizce olmayan herhangi bir şey kod pasajı olma şansının% 99.9'una sahiptir .

Yani benim çözüm olacaktır: Orada birçok İngilizce dil-dama birini kullanın (çift noktalar veya benzeri olmayan dil sembolleri gibi sözdizimi hataları - - yazım hataları yanında sadece onlar da sinyal emin olun #veya ~). O zaman büyük miktarda hata ve uyarı veren herhangi bir satır / paragraf, "bu kod mu?" soru.

Bu yaklaşım elbette İngilizce dışındaki dilleri kullanan StackExchange siteleri için de uyarlanabilir.

Sadece benim 2 ¢ ...


16
Sorun, gelen soruların pek çoğunun İngilizce olmaması (buna benzer olmasına rağmen).
Brendan Long

3
@Brendan - Bu teklifin avantajı o zaman eklendi: yazının muhtemel olarak İngilizce olması gereken bölümlerindeki hataların altını çizin (ya da vurgulayın) ve yazarın İngilizce yazmasına yardımcı olun! ;)
mac

1
Hollandalıyım ve kodladığım her şey İngilizce dilinde, yorumlara göre değil (projeye bağlı olarak). Bu yüzden İngilizce olmayan kod yeterli olmayacaktır. Yani ya da bozuk İngilizce'nin kod olması gerektiği anlamına geliyor.
Ivo Limmen

@Ivo - Benim yorumum şaka olarak İngilizce sorununa hitap edildi! ;) Bununla birlikte, başka bir dilde yaptığım önerilerin sadece iyi sonuç vereceğini söyleyebilirim… OTOH’un İngilizce’deki blok yorumları “bu kod mu?” soru, ama bu sorun değil, çünkü yorumun yazıldığı kod zaten onu tetiklemiş olacaktı ...
mac

11

Muhtemelen bunun için birkaç oy alacağım ama bence yanlış açıdan yaklaşıyorsun.

Bu hat beni yakaladı:

insanların girmesi ve bir şekilde bunu çözemeyen insanlar için kodu manuel olarak biçimlendirmesi gerekiyor

IMO bu bakış açısı kibirli bir şey. Bunu, programcıların ve tasarımcıların, problemi kullanıcı değil, yazılımın kendisi veya en azından kullanıcı arayüzü olmadığında, yazılımı doğru şekilde nasıl kullanacaklarını anlayamayan kullanıcılara kızdırdıkları yazılım tasarımında çok buluyorum.

Bu sorunun kök nedeni kullanıcı değil, onlar için bunu yapabileceklerinin açık olmadığı gerçeğidir.

Bunu daha açık hale getirmek için UI'deki bir değişikliğe ne dersiniz? Elbette bu olacak:

  1. Yeni kullanıcılar için tam olarak ne yapmaları gerektiği daha açık
  2. çok sayıda dilin kod mantığını tespit etmek için karmaşık algoritmalar yazmak yerine oluşturmak için daha kolay

Örnek:

görüntü tanımını buraya girin


26
Aslında bu IMO, "Lütfen bir sorunum var, bana yardım edin, kod aşağıda." Gibi kötü soruları zorlar - kodun sorudan oldukça nadiren ayrılması gerekir. En iyi sorular şöyle gider: "Bunu başarmak istiyorum ve bu iki kod satırını yazdım, ama sonuç şu, sorun ne?" - sade bir dille yoğun şekilde yerleştirilmiş çok az kod var.
sharptooth

4
Kök gözlem doğrudur ancak tanı hala yanlış: aslında, Jeff olan bu yaklaşım ile kullanıcı arayüzü geliştirmeye çalışıyor. Ayrıca, şu anki UI zaten birkaç döngüden geçmiştir ve geliştirilebileceğinden şüphem olmasam da (şiddetli bir şekilde) bunun tembel aptallara karşı yardımcı olacağından şüpheliyim. Sizin de önerilen çözümünüz olmazdı. @sharptooth bu kaplı.
Konrad Rudolph

2
Kutuyu düşünmek için + 1'im olur ama belirli bir öneriye katılmıyorum, çünkü "destekleyici kod" yazmak doğal olmayan bir soru akışını zorlar. Ben sadece sorumun altındaki kodda bırakmadım. Neredeyse her zaman bir intro gönderirim, örnek kod, sonra asıl soru. Bu önermeyi satır içi kodun şart olduğunu kabul ederseniz, kullanıcı tarafından girilmesi veya sistem tarafından önerilen biçimlendirme gerekir. Ve Jeff'in yapmak istediği tam olarak bu.
Nicole,

1
@Konrad: Yukarıdaki yorumuma ek olarak ve sizinkilerinize cevaben, Jeff'in bu yolu izleyerek UI'yi iyileştirdiğine inanmıyorum, fakat sadece temelde yatan bir sorunun semptomlarını tedavi ediyorum. Kullanıcı arayüzü, hatanın oluşmaması için iyileştirildiyse kullanıcıyı uyarma çözümü gerekmez. Örneğimin nihai çözüm olduğu yanılsamam, ancak bazı düşüncelerin "bunu mümkün olan en iyi şekilde mi sunuyoruz?" Sorusuna girmesi gerekiyor.
matt_asbury 28:11

1
Basit cümle kodunu{} metin kutusunun etrafındaki düğmeyi kullanarak işaretlemek yeterli olabilir.
Paŭlo Ebermann

11

Sözde kod gerçek bir sorun teşkil edecektir, çünkü tüm programlama dili '[]', ';', '()' vb. Gibi özel karakterlere dayanır. Bu özel karakterlerin oluşumunu saymanız yeterlidir. Tıpkı bir ikili dosya tespit ettiğiniz gibi (örneğin% 5'inden fazlası 0 bayt değeri içeriyor).


Bunu, [] () gibi bu özel karakter gruplarına sahip olmak kadar iyileştirirdim; {} =. İçerdiği bu grupların 2-3'ünden fazlasına sahip olan her satır bir kod satırıdır.
Honza

... ve ayrıca en yaygın dillerde ortak dizeleri arayın, örneğin "= someword ();" Kıvrımlı parantez dillerinin çoğu için, "<something>" ve "<ab: cde>" gibi XML benzeri sözdizimi ve diğer dillerdeki diğer ortak dizeler. Uygulanacak yeni dilleri bulduğunuzda genişletebileceğiniz için, ortak sözdiziminin bir tür arama tablosunun iyi bir çözüm olduğuna inanıyorum.
Arve Systad

Muhtemelen sözde kodunu bırakmalısın. Bazı insanlar C tarzı dili olarak yazmak ister ama diğer insanlar VB6 daha yakın görünüyor şeyle ingilizce düz kullanacak
James P.

4

Bence bunu sadece belirli dillere karşı hedeflemeniz gerekebilir, genel olarak bu problem İngilizce'ye oldukça benzeyen dilleri alabileceğiniz için anlaşılmazdır (örneğin, inform7 ). ama neyse ki en çok kullanılanlar oldukça kolay bir şekilde kaplanabilirdi.

İlk kesimlerim size C, C ++, Java, C # ve benzer bir sözdizimi kullanan diğer diller için iyi bir eşleşme sağlayacak olan "; \ n" dizisini aramak olacak. İngilizcede, a'dan daha az kullanılması muhtemeldir; yeni satır olmadan


artı belki de bol miktarda kaşlı ayraçlar; p
Marc Gravell

1
Jeff'in görevinde dediği gibi, muhtemelen sadece ana dilleri hedef alacaklardı. Her halükarda, yeni kullanıcıların (bu işlevselliği amaçlayanlar için) C # veya Javascript verme olasılıklarının INTERCAL ;-)
Ben

Evet, ancak bu BRAINFUCK veya BLANK programlama dili ile çalışmaz. ;-)
Ivo Limmen

4

Birisi etiketlere bakmaktan ve bunun için sözdizimi aramaktan bahsetti ama bu yeni kullanıcılara yönelik olduğu için düşürüldü.

Muhtemel daha iyi bir çözüm, sorunun gövdesindeki dil adlarını aramak ve ardından aynı stratejiyi uygulamak olacaktır. Eğer "Javascript", "Java" veya "C #" den bahsedersem, ihtimal budur ve sorudaki kod o dilde olabilir.


Özellikle, "vb c # .net dot net bana yardım etmeme yardım et!"
NickAldwin

1

Öncelikle, yazım denetiminden geçirin, çok az uygun İngilizce kelime bulacak, ancak yazım denetleyicisinin ayrılmasını önereceği çok fazla kelime olması gerekir.

Daha sonra, düz İngilizce için tipik olmayan, kod için tipik olan noktalama işaretleri / özel karakterler vardır:

  • something(); sadece düz İngilizce olamaz;
  • $somethingnerede somethingtüm sayısal değildir;
  • -> boşluksuz kelimeler arasında;
  • . boşluksuz kelimeler arasında;

Elbette iyi çalışması için, bu özelliklerin üstüne kurulu Bayesian sınıflandırıcıya sahip olmak isteyebilirsiniz.


1
() İçeren girintili olmayan bir çizgiyi algılama; mesajı önermek için iyi bir sebep olurdu.

Hangi yazım denetleyicisi kod yapıştırılmadan önce boğulmaz?
Tim Post

Yerli olmayan İngiliz yazarların yazdığı bazı mesajlarla yazım denetleyici diğer her kelimeyi boğacak ...
PhiLho

@Ph: Bu soru / cevaplar zaten SO'da kabul edilmez.
vartec

1

Benzer sözdizimini paylaşan birkaç dil seti vardır. çoğu dil birkaç dilden etkilendiğinden, diller [AMPL, AWK, csh, C ++, C--, C #, Amaç-C, BitC, D, Go, Java, JavaScript, Limbo, LPC, Perl, PHP, Pike, Processing [hepsi C'den etkilendi, bu yüzden C'yi tespit ederseniz, muhtemelen bütün bu dilleri tespit edeceksiniz. bu yüzden sadece bu dil gruplarını tespit etmek için basit bir kalıp yazmanız gerekiyor.

Ben de metni bloklara bölerim çünkü çoğu kod iki yeni satırla bölünür ya da yazıdaki diğer metin bloklarından benzer şekilde bölünür.

Bu, javascript (c ailesi için üst düzey eksik bir örnek) ile kolayca yapılabilir:

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

Her satır için sadece kelimeleri / noktalama karakterlerini sayın. İngilizce 4 veya daha fazla, kod 2'den küçük olma eğilimindedir.

Yukarıdaki paragrafta 18 kelime ve örneğin 4 noktalama işareti bulunur. Bu paragrafta 19 kelime ve 4 noktalama işareti var.

Tabii ki, bu acemi ingilizce olmayan ingilizce konuşmacıların sorularına karşı test edilmek zorunda kalacak ve bu durumlarda, istatistiklerin çarpık olması olabilir.

[Boşluk olmayan] [boşluk veya yeni satır] kodunda çok nadir, ancak İngilizce olarak yaygın olduğundan, bunun noktalama değil, kelime olarak sayılabileceğini umuyorum.

En büyük sorunun, birinin aşağıdaki gibi bir soru sorduğu satır içi kod olacağını düşünüyorum:

(İ = 0; i> 100; i ++) {} için söylersem bunun anlamı nedir?

Bu kod ve İngilizcedir ve geri tıklamalardaki gibi işaretlenmelidir:

Bunun for (i=0; i>100; i++) {}ne anlama geldiğini söylersem ?


0

Öncelikle, yalnızca gerçekten belirtilmesi gereken (yeterince) biçimlendirilmiş kod ile yine de manuel olarak biçimlendirilmesi gereken (çok) zayıf biçimlendirilmiş kod arasında bir ayrım yapmanız gerektiğini düşünüyorum.

Biçimlendirilmiş kod kesme çizgileri ve girintiye sahiptir. Yani: bir çizgiden önce gelen tek bir kesme çizgisi varsa, iyi bir adayınız olur. Bunun üzerinde önde gelen boşluklar varsa, çok iyi bir adayınız vardır.

Normal metin biçimlendirme için iki kesme çizgisi veya iki boşluk ve bir kesme çizgisi kullanır, bu nedenle ayrım için net bir ölçüt vardır.

LISP kodunda noktalı virgül bulamazsınız, Ruby kodunda parantez bulamazsınız, sözde kodda fazla bir şey bulamayabilirsiniz. Ancak (ezoterik olmayan) herhangi bir dilde, kesme çizgileri ve girintilerle biçimlendirilecek iyi kod bulacaksınız. Bunun kadar evrensel bir şey yok. Çünkü kodun sonunda insanlar tarafından okunmak üzere yazılmıştır.

İlk önce potansiyel kod satırlarını arayın . Ayrıca, kod satırları genellikle gruplar halinde gelir. Eğer bir tane varsa, yukarıdaki ya da altındaki olanın da bir kod satırı olma ihtimali yüksektir.

Potansiyel kod satırlarını seçtikten sonra, bunları ölçülebilir kriterlere göre kontrol edebilir ve bazı eşikler seçebilirsiniz :

  • kelime olmayan karakterlerin sıklığı
  • tanımlayıcıların sıklığı: CamelCase veya under_score stiliyle çok kısa kelimeler veya çok uzun kelimeler
  • nadir kelimelerin tekrarı

Ayrıca, şimdi programcılar ve c'ler olduğu için, stackoverflow'un kapsamı açıkça daraltılmıştır. Bir kişi tüm dil etiketlerini dil olarak göstermeyi düşünebilir. Ve gönderim yaparken, en az bir dil etiketi seçmeniz, language-agnosticetiketi seçmeniz veya açıkça ihmal etmeniz istenir .

İlk durumda, hangi dilleri arayacağınızı biliyorsunuz, ikinci durumda, sözde kod aramak isteyebilirsiniz ve son durumda, muhtemelen herhangi bir kod olmayacaktır, çünkü bazı teknolojilerle ilgili bir soru veya çerçeve ya da böyle.


0

Tespit etmek istediğiniz her dil için bir çözümleyici oluşturabilirsiniz (ANTLR için dil tanımlarını bulmak genellikle kolaydır), ardından sorunun her satırını her ayrıştırıcıdan geçirin. Herhangi bir satır doğru ayrıştırıyorsa, muhtemelen kodunuz vardır.

Bununla ilgili sorun, bazı ingilizce (doğal dil) cümlelerin kod olarak ayrıştırılması olabilir, bu nedenle diğer fikirlerin bazılarını da dahil etmek isteyebilirsiniz veya yalnızca bir veya ikiden fazla satır doğru bir şekilde ayrılırsa pozitif sonuçları sınırlayabilirsiniz. aynı dil ayrıştırıcı.

Diğer olası sorun, bunun muhtemelen yalancı kod almayacağıdır, ancak bu doğru olabilir.


Çoğu zaman insanlar kodlarında sözdizimi hataları yaparlar (ve bunu soruyorlar).
Paŭlo Ebermann

0

Diğer diller (şu anda en çok kullanılan programlama dillerinden biraz farklı görünüyor) daha popüler hale geldiğinden ve şu anda kullanılan diller daha az popüler hale geldiğinden, uzun vadede en geleceğe en uygun olabilecek ve en az manuel ayar gerektirebilecek olan şey Google Translate'in yaptığı gibi bir şey (ab ve a () gibi bazı şeyleri aramak yerine "Nasıl çalışır?" başlıklı paragrafa bakın).

Başka bir deyişle, aranacak kodda bulunan kalıpları manuel olarak düşünmek yerine , bilgisayar bunu kendi başına çözebilir . Bu yapılarak yapılabilir

  1. birçok farklı programlama dilinde çok sayıda kod

    • Öneri: Google Code veya Github gibi web tabanlı kaynak kod havuzlarından veya hatta zaten kod olarak işaretlenmiş Stackoverflow'ta bulunanlardan kod örneklerini otomatik olarak alın

    • Not: Kod yorumlarını ayrıştırmak iyi bir fikir olabilir

  2. web’deki makalelerden alınan çok sayıda ingilizce metin

    • programlama ile ilgili makalelerden olmamasına rağmen (aksi halde kodları olabilir ve sistemi karıştırırlar :-))

ve bir tür algoritmaya sahip olmak otomatik olarak ingilizce olmayan koddaki kalıpları bulur ve bunun tersi olur ve algoritmayı yayınlarda çalıştırarak kodun ne olduğunu ve kodun olmadığını saptamak için bu kalıpları kullanır.

(Ancak, böyle bir algoritmanın nasıl çalışacağından emin değilim. Mevcut soruya verilen diğer cevaplar bunun için yararlı bilgilere sahip olabilir.)

Ardından sistem, kodun o andaki bakış açısındaki değişiklikleri hesaba katarak kodları her seferinde bir kez yeniden tarayabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.