在一段代码中检测使用哪种编程语言的最佳方法是什么?
我认为垃圾邮件过滤器中使用的方法可以很好地工作.您将片段拆分为单词.那么你应该比较这些词与已知的片段中的出现次数,并计算这个片段是用语言X为你感兴趣的每一种语言的可能性.
http://en.wikipedia.org/wiki/Bayesian_spam_filtering
如果您有基本机制,那么添加新语言非常容易:只需使用新语言的一些片段训练检测器(您可以将其作为开源项目提供).通过这种方式,它了解到"系统"可能会出现在C#片段中,并且"放入"Ruby片段中.
我实际上已经使用这种方法将语言检测添加到论坛软件的代码片段中.除了模棱两可的情况外,它在100%的时间内都有效:
print "Hello"
让我找到代码.
我找不到代码所以我做了一个新代码.它有点简单,但它适用于我的测试.目前,如果你提供比Ruby代码更多的Python代码,它可能会说这段代码:
def foo puts "hi" end
是Python代码(尽管它确实是Ruby).这是因为Python也有一个def
关键字.因此,如果它已经def
在Python 中看到了1000x 而def
在Ruby中看到了100x ,那么它可能仍然会说Python,尽管puts
它end
是特定于Ruby的.您可以通过跟踪每种语言所看到的单词并将其除以某处(或通过在每种语言中提供相同数量的代码)来解决此问题.
我希望它可以帮助你:
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)
语言检测由他人解决:
Ohloh的方法:https://github.com/blackducksw/ohcount/
Github的方法:https://github.com/github/linguist
您可以在这里找到一些有用的资料:http://alexgorbatchev.com/wiki/SyntaxHighlighter.Alex花了很多时间来弄清楚如何解析大量不同的语言,以及关键的语法元素是什么.
Guesslang是一个可能的解决方案:
http://guesslang.readthedocs.io/en/latest/index.html
还有SourceClassifier:
https://github.com/chrislo/sourceclassifier/tree/master
在博客文章中找到一些我无法识别的代码后,我对这个问题产生了兴趣.添加此答案,因为这个问题是"识别编程语言"的第一次搜索.
这很难,有时甚至是不可能的.这个简短的片段是哪种语言的?
int i = 5; int k = 0; for (int j = 100 ; j > i ; i++) { j = j + 1000 / i; k = k + i * j; }
(提示:它可能是几个中的任何一个.)
您可以尝试分析各种语言,并尝试使用关键字的频率分析来决定.如果某些关键字在文本中以某些频率出现,那么该语言很可能是Java等.但我认为你不会得到任何完全傻瓜证明的东西,因为你可以命名为例如同名C中的变量作为Java中的关键字,频率分析将被愚弄.
如果你把它提高到一个复杂程度,你可以寻找结构,如果某个关键字总是在另一个关键字之后,那将为你提供更多线索.但是设计和实施起来也会困难得多.
另一种方法是使用highlight.js,它执行语法突出显示,但使用突出显示过程的成功率来识别语言.原则上,任何语法高亮显示器代码库都可以以相同的方式使用,但highlight.js的优点是语言检测被认为是一个功能并用于测试目的.
更新:我试过这个并没有那么好用.压缩的JavaScript完全混淆了它,即标记化器对空白敏感.一般来说,只计算高亮点击似乎不太可靠.更强大的解析器,或者可能无法匹配的节数,可能会更好.