检测代码片段中使用了哪种编程语言的最佳方法是什么?
发布于 2009-01-23 23:21:41
我认为垃圾邮件过滤器中使用的方法会工作得很好。您将代码片段拆分成单词。然后,将这些单词的出现次数与已知代码片段进行比较,并计算您感兴趣的每种语言使用X语言编写此代码片段的概率。
http://en.wikipedia.org/wiki/Bayesian_spam_filtering
如果您有基本的机制,那么添加新语言就很容易了:只需用新语言训练检测器(您可以将其作为一个开源项目)。通过这种方式,它了解到“系统”可能出现在C#片段中,而"puts“则出现在Ruby片段中。
实际上,我已经使用此方法将语言检测添加到论坛软件的代码片段中。它在100%的情况下都是有效的,除非在不明确的情况下:
print "Hello"
让我找找代码。
我找不到代码,所以我做了一个新的。这有点简单,但它适用于我的测试。目前,如果你提供给它的Python代码比Ruby代码多得多,你可能会说这段代码:
def foo
puts "hi"
end
是Python代码(尽管它实际上是Ruby)。这是因为Python也有一个def
关键字。因此,如果它在Python语言中看到了1000x的def
,在Ruby语言中看到了100x的def
,那么即使puts
和end
是特定于Ruby语言的,它仍然可能使用Python语言。您可以通过跟踪每种语言看到的单词并除以某个位置(或在每种语言中提供相等数量的代码)来修复此问题。
我希望它能帮助你:
class Classifier
def initialize
@data = {}
@totals = Hash.new(1)
end
def words(code)
code.split(/[^a-z]/).reject{|w| w.empty?}
end
def train(code,lang)
@totals[lang] += 1
@data[lang] ||= Hash.new(1)
words(code).each {|w| @data[lang][w] += 1 }
end
def classify(code)
ws = words(code)
@data.keys.max_by do |lang|
# We really want to multiply here but I use logs
# to avoid floating point underflow
# (adding logs is equivalent to multiplication)
Math.log(@totals[lang]) +
ws.map{|w| Math.log(@data[lang][w])}.reduce(:+)
end
end
end
# Example usage
c = Classifier.new
# Train from files
c.train(open("code.rb").read, :ruby)
c.train(open("code.py").read, :python)
c.train(open("code.cs").read, :csharp)
# Test it on another file
c.classify(open("code2.py").read) # => :python (hopefully)
发布于 2012-03-13 06:11:30
其他人解决的语言检测:
Ohloh的方法:https://github.com/blackducksw/ohcount/
Github的方法:https://github.com/github/linguist
发布于 2018-02-27 18:20:24
Guesslang是一种可能的解决方案:
http://guesslang.readthedocs.io/en/latest/index.html
还有SourceClassifier:
https://github.com/chrislo/sourceclassifier/tree/master
在一篇博客文章中发现了一些我无法识别的代码后,我开始对这个问题感兴趣。添加这个答案,因为这个问题是“识别编程语言”的第一个搜索命中。
https://stackoverflow.com/questions/475033
复制相似问题