更快的文件编程语言检测器

2021-01-17 01:58:25

编程语言检测器和工具箱,用于忽略二进制或供应商的文件。 enry最初是Go语言的原始Linguist Ruby库的移植端口,它的性能提高了2倍。

enry还是一个Go库,用于猜测一种通过FFI将API公开给多个编程环境的编程语言。

enry使用一系列匹配策略来猜测一种编程语言,这些策略逐渐应用于缩小可能的选择范围。每种策略都会根据需要决定的输入数据类型而有所不同:文件名,扩展名,文件的第一行,文件的完整内容等。

根据可用的输入数据,enry API可以大致分为以下几类或用例。

要仅根据文件的内容或文本片段进行猜测,请使用

GetLanguageByModeline用于Vim / Emacs modeline例如/ * vim:设置ft = cpp:* /可能出现在文本的开头或结尾。

它通常是最后一种策略,用于消除对先前策略的猜测的歧义,因此,它需要" candidate"的列表。猜。可以提供所有已知语言的列表-数据中的键。如果没有更智能的假设,则语言LogProbability作为可能的候选者,但代价可能是次优的准确性。

当文件名和内容均可用时,最准确的猜测是:

GetLanguages使用全套匹配策略,并且预计是最准确的。

enry公开了一组文件级助手Is *,以简化筛选出出于源代码分析目的而不太有趣的文件:

enry公开函数以获取语言颜色,例如用于在图形中显示统计信息:

GetLanguageGroup可用于将相似的语言分组在一起,例如对于更少,此函数将返回CSS

其余示例将假定您已完成此操作或将库提取到了GOPATH中。

//此处和下面的示例假定您已导入库。导入" github.com/go-enry/go-enry/v2" lang,安全:= enry。 GetLanguageByExtension(" foo.go")fmt。 Println(lang,safe)//结果:设为true lang,safe:= enry。 GetLanguageByContent(" foo.m&#34 ;, []字节("< matlab-code>"))fmt。 Println(lang,safe)//结果:Matlab真正的lang,safe:= enry。 GetLanguageByContent(" bar.m&#34 ;, []字节("< objective-c-code>"))fmt。 Println(lang,safe)//结果:Objective-C true //所有策略一起lang:= enry。 GetLanguage(" foo.cpp&#34 ;, [] byte("< cpp-code>"))//结果:C ++ true

请注意,如果仅检测到一种可能的语言,则返回的布尔值safe为true。

同一API的复数形式允许获取给定文件的所有可能语言的列表。

langs:= enry。 GetLanguages(" foo.h&#34 ;, [] byte("< cpp-code>"))//结果:[] string {" C&#34 ;, " C ++"," Objective-C} langs:= enry。 GetLanguagesByExtension(" foo.asc&#34 ;, [] byte("< content>"),nil)//结果:[] string {" AGS Script" ," AsciiDoc","公钥"} langs:= enry。 GetLanguagesByFilename(" Gemfile&#34 ;, [] byte("< content>"),[] string {})//结果:[] string {" Ruby&#34 ;}

一个用于macOS和linux平台的库以tech.sourced:enry-java在Maven上发布。 Windows支持计划在src-d / enry#150下进行。

库将在pypi上作为enry formacOS和linux平台发布。 Windows支持计划在src-d / enry#150下进行。

" .txt"的启发式Vim帮助文件中的扩展名无法解析,因为RE2正则表达式引擎中不支持的负前瞻。

" .sol"的启发式由于RE2正则表达式引擎中不支持的负前瞻,因此无法解析Solidity中的扩展。

" .es"的启发式 由于RE2正则表达式引擎中不支持反向引用,因此无法解析JavaScript中的扩展名。 " .rno"的启发式 由于RE2正则表达式引擎中不支持的提前查询,因此无法解析RUNOFF中的扩展名。 " .inc"的启发式 由于RE2正则表达式引擎中不支持的所有格量词,因此无法解析NASL中的扩展名。 " .as"的启发式 由于RE2正则表达式引擎中不支持的正向超前功能,因此无法解析ActionScript中的扩展名。 从Linguist v5.3.2开始,它在C中使用基于Flex的扫描器进行标记化。 Enry仍然使用基于正则表达式的extract_token算法。 参见#193。 尚不支持检测生成的文件。(因此,它们不会从CLI输出中排除)。 参见#213。 在上述所有情况下,都有问题编号-我们计划更新enry以匹配语言学家的行为。

直方图显示每个时间段存储区(x轴)的文件数(y轴)。enry可以更快地检测到大多数文件。

在某些情况下,由于Go正则表达式引擎比Ruby慢,因此enry比Linguist慢,这是基于用C编写的oniguruma库。

在电影《我的淑女》中,亨利·希金斯教授是一位语言学家,在电影的一开始就喜欢根据口音来猜测人们的出身。

将ENRY_TEST_REPO设置为现有语言学家结帐的路径将避免克隆和单独进行测试。设置ENRY_DEBUG = 1将提供make代码生成完成的贝叶斯分类器构建的见解。

enry重用原始github / linguist的一部分来生成内部数据结构。为了更新到最新版本的语言,请执行以下操作:

$ git clone https://github.com/github/linguist.git .linguist $ cd .linguist; git checkout< release-tag> ; cd ..#将新发行版本的提交sha放在generator_test.go中(以重新生成.gold测试装置)#https://github.com/go-enry/go-enry/blob/13d3d66d37a87f23a013246a1b0678c9ee3d524b/内部/代码生成器/生成器/生成器_test.go#L18 $使代码生成

为了保持同步,当新版语言学家对以下任何文件进行更改时,都需要更新enry:

没有自动检测语言项目中的更改的功能,因此上述过程必须不时手动进行。

提交与新版本同步的拉取请求时,请确保它仅包含所生成文件(在数据子目录中)的更改。

分隔所有必需的"手册"代码更改为不同的PR,其中包括一些背景说明以及对"与语言学家的分歧的文档的更新。非常感谢,因为它简化了维护(查看/发行说明/等)。

获得主要检测功能的平均时间和整个样本集的策略。如果要查看每个样本文件的度量,请执行以下操作:

它将运行enry和Linguist的基准测试,解析输出,创建csv文件并绘制直方图。

Oniguruma是CRuby的正则表达式引擎,它非常快并且比Go运行时内置的引擎性能更好。由于rubex项目,enry支持在这两个引擎之间进行交换。使用Oniguruma的典型总体速度为1.5-2倍。但是,它需要CGo和外部共享库。在具有Homebrew的macOS上,它是: