【发布时间】:2017-02-09 05:11:07
【问题描述】:
我正在编写的 Python 应用程序需要从源代码中提取标识符和文本字符串。它发现的一小部分是(看似)随机字符串。我想过滤掉它们,但到目前为止还不能创建一个正则表达式来做到这一点。仅按长度过滤是不可能的,因为有一些非常长的标识符是有效的。这是一个随机抽取的示例,与相同长度的有效标识符相比:
UGxhemEgZGUgaWZXNaWdhZGyOiBDSUWRVNUQVYtSVBOIFVuaWQ
NSApplicationDidChangeScreenParametersNotification
有没有办法编写一个正则表达式或其他检测系统来检测这样的垃圾序列?我开始怀疑如果不对大型单词字典测试字符串就无法做到这一点,我认为这很容易出错并且是计算密集型的。但是,也许更聪明的人知道这样一种检测或匹配随机序列的方法?
这个问题的理想解决方案是一个函数,它可以将字符串作为输入,并报告它是否“可能”是随机的。它可能会产生误报(错误地将一些随机字符串误报为非随机字符串),最好概率很低,但它不能报告误报(有些东西不是随机的)。以防万一,字符串的长度似乎在 25 到 80 个字符之间。
EDIT #1 2017-02-08:进一步思考,我想到一种可能的方法可能是匹配行中最少数量的唯一字符的正则表达式。例如,第二个字符必须与第一个不同,第三个与前两个不同,第四个与前三个不同,等等。足够长的版本可能会捕获很多随机序列。但是,查看不同的正则表达式运算符,我没有看到(因为缺少更好的词)“负反向引用”或“匹配的东西 other 而不是你刚刚匹配的东西”的版本。如果有人知道这方面的变化,也许我可以让它工作。
EDIT #1 2017-02-10:我担心我编写上面两个示例字符串的方式可能会被误解为单个字符串。上面的例子是两个相同长度的独立字符串——如果不清楚,我深表歉意。这里还有一些例子;每行都是一个单独的标识符。这也是故意显示不同的长度。
shouldBeAbleToCountLiveNeighboursOfACellOnDiagonalsAndStraightLines
eXNZWzIGbHRpbWVkaWEgYWkIGFuaWhdGlvbiBkaXNcmlidXRlZCNCpUgRGlzdHJpYnV
dWxLXRvbGVyYWIHJlYWwtdGltZSBzeXNZWzLgKlSBEaXNcmlidXRlZCBBcmNoaXRlYR
dGhIExvIHNYmltbMgYSBsYSBwWdpbmEgeSBsbyBhbnVuYlhbWzIGVuIGVsIHByhpbWg
aGUgYuZmVyZWjZSBwcmjZWVkaWncygDQoNClNYmpcNpbNCkluIGyZGVyIHRvIHN
YQKUGFyYTogZXNYFyQGluYWlcCteAKQMIExaXMgQSgUGluZWRhDQpDQzogQuYVw
thehasSizeMatcherShouldMatchACollectionWithExpectedSize
QycmVvIGRlIERpcVtaWhYnDsgZGUgYWNaXZpZGFkZXMgZGUgbGEg
NSAppleEventManagerWillProcessFirstEventNotification
SNMTransformGizmoRotationControllerPerformTransform
RndkOiBEaWZcnDsgZGUgYudmjYXRvcmlhIFNVTUJVCBlbiBSRUJ
不管它有什么价值,我把我的应用程序从大约 900 个 GitHub 存储库的半随机选择中提取的 pastebin a list of the 1000 longest identifiers 放在了上面。它包含真实标识符和随机字符串。
【问题讨论】:
-
NLTK 可能对此有用。
-
假设有效标记包含英语,无效标记将有更多的 4 个或更多连续辅音。
-
乍一看,如果字符串长度足够大(25-80 可能还可以),那么如何计算每个字母的频率,并将这个分布与典型的英语语言进行比较。
-
这些想法很有趣,swbandit 和 Roman Fursenko。谢谢!我将探索它们。我特别喜欢@swbandit 的想法,因为它可以表示为正则表达式。
-
@swbandit 你的想法让我成功了一半。事实证明,由于其中一些字符串是标识符,它们有时是多个单词的串联,因此不遵循典型的字母分布。但是,将连续 10 个辅音的正则表达式与最小长度限制组合在一起可以捕获所有非常长的字符串。这就是进步!谢谢。
标签: python regex random pattern-matching