计算机是否能够通过用户提供的样例来“学习”正则表达式?
澄清一下:
- 我不想学习正则表达式。
- 我想创建一个程序,该程序可以从用户交互提供的示例中“学习”正则表达式,例如通过从文本中选择部分或选择起始或结束标记。
是否有可能? 有没有算法、关键词等可供Google搜索?
编辑: 感谢各位的回答,但我对提供此功能的工具不感兴趣。 我正在寻找理论信息,如论文、教程、源代码、算法名称,以便我可以为自己创建一些东西。
计算机是否能够通过用户提供的样例来“学习”正则表达式?
澄清一下:
是否有可能? 有没有算法、关键词等可供Google搜索?
编辑: 感谢各位的回答,但我对提供此功能的工具不感兴趣。 我正在寻找理论信息,如论文、教程、源代码、算法名称,以便我可以为自己创建一些东西。
是的,我们可以根据示例(文本->期望的提取结果)生成正则表达式。这是一个在线工具,可以完成此工作:http://regex.inginf.units.it/
Regex Generator++在线工具使用GP搜索算法从提供的示例生成正则表达式。该GP算法受多目标适应度驱动,可导致更高的性能和更简单的解决方案结构(奥卡姆剃刀)。这个工具是Trieste大学(Università degli studi di Trieste)机器学习实验室的演示应用程序。请在这里查看视频教程。
这是一个研究项目,因此您可以在这里阅读所使用的算法。
请注意! :-)
如果所提供的示例很好地描述了问题,那么从示例中找到有意义的正则表达式/解决方案是可能的当且仅当。请考虑下面描述提取任务的示例,我们正在寻找特定的项目代码; 示例是文本/提取对:
"The product code is 467-345A" -> "467-345A"
"The item 789-345B is broken" -> "789-345B"
一个(人类)男性,看着这些例子可能会说:“这些项目代码看起来像\d++-345[AB]”
当项目代码更加宽容但我们没有提供其他例子时,我们没有证据来更好地理解问题。 当应用人类生成的解决方案\d++-345[AB]到以下文本时,它失败了:
"On the back of the item there is a code: 966-347Z"
您需要提供其他示例,以更好地描述什么是匹配和什么不是所需的匹配: --例如:
"My phone is +39-128-3905 , and the phone product id is 966-347Z" -> "966-347Z"
电话号码不是产品ID,这可能是一个重要的证据。
这本名为《计算学习理论导论》的书包含了一种学习有限自动机的算法。由于每个正则语言都等价于一个有限自动机,因此可以通过程序学习一些正则表达式。Kearns和Valiant展示了一些无法学习有限自动机的情况。相关问题是学习隐马尔可夫模型,它们是能够描述字符序列的概率自动机。请注意,大多数现代编程语言中使用的“正则表达式”实际上比正则语言更强大,因此有时更难以学习。
(111111|999999)
2. 匹配6个相同数字的正则表达式:(\d)\1{5}
3. 匹配6个1或9的正则表达式:[19]{6}
4. 匹配任意6个数字的正则表达式:\d{6}
5. 上述三种中的任何一种,带有单词边界,例如:\b\d{6}\b
6. 上述前三种中的任何一种,不被数字前后跟随,例如:(?<!\d)\d{6}(?!\d)
正如您所看到的,有许多方法可以将示例概括为正则表达式。 计算机建立可预测的正则表达式的唯一方法是要求您列出所有可能的匹配项。 然后它可以生成一个搜索模式,精确地匹配这些匹配项。当然可以创建一个工具,它使用用户提供的指南和示例文本来生成正则表达式。设计这样一个工具的难点在于如何询问用户需要的指导信息,而不使工具比学习正则表达式本身更难,并且不限制工具仅适用于常见的正则表达式任务或简单的正则表达式。
是的,这当然是“可能的”;以下是伪代码:
string MakeRegexFromExamples(<listOfPosExamples>, <listOfNegExamples>)
{
if HasIntersection(<listOfPosExamples>, <listOfNegExamples>)
return <IntersectionError>
string regex = "";
foreach(string example in <listOfPosExamples>)
{
if(regex != "")
{
regex += "|";
}
regex += DoRegexEscaping(example);
}
regex = "^(" + regex + ")$";
// Ignore <listOfNegExamples>; they're excluded by definition
return regex;
}
@Yuval是正确的。您正在查看计算学习理论或“归纳推理”。
这个问题比您想象的要复杂,因为“学习”的定义并不是微不足道的。一个常见的定义是,学习者可以随时吐出答案,但最终必须停止吐出答案或始终吐出相同的答案。这假定有无限数量的输入,并且对程序何时达到决策没有任何保证。此外,您无法确定它何时已经做出决定,因为它可能稍后仍会输出不同的内容。
按照这个定义,我相信常规语言是可以被学习的。但根据其他定义,情况就不一定了...