计算机是不是可以通过用户提供的示例“学习”正则表达式?

Posted

技术标签:

【中文标题】计算机是不是可以通过用户提供的示例“学习”正则表达式?【英文标题】:Is it possible for a computer to "learn" a regular expression by user-provided examples?计算机是否可以通过用户提供的示例“学习”正则表达式? 【发布时间】:2010-10-11 14:31:37 【问题描述】:

计算机是否可以通过用户提供的示例“学习”正则表达式?

澄清一下:

我确实想学习正则表达式。 我想创建一个程序,从用户交互式提供的示例中“学习”正则表达式,可能通过从文本中选择部分或选择开始或结束标记。

有可能吗?是否有算法、关键字等我可以谷歌搜索?

编辑:感谢您的回答,但我对提供此功能的工具不感兴趣。我正在寻找理论信息,例如论文、教程、源代码、算法名称,以便我可以为自己创造一些东西。

【问题讨论】:

我很惊讶没有人提到Regex::PreSuf 任何人都知道是否有一个 python 等效于 Regex::PreSuf 【参考方案1】:

你可能想玩一下这个网站,它很酷,听起来和你所说的类似:http://txt2re.com

【讨论】:

【参考方案2】:

我相信这个词是“感应”。你想归纳出一个正则语法。

我认为有限的示例集(正面或负面)是不可能的。但是,如果我没记错的话,如果有可以咨询的 Oracle 就可以做到。 (基本上你必须让程序问用户是/否问题,直到它满足为止。)

【讨论】:

是的,这就是我想做的,以交互方式询问用户。 Yuval F 的参考资料似乎是我的想法,我建议看看那些。【参考方案3】:

如果一个人可以学习一个正则表达式,那么它从根本上来说是一个程序是可能的。但是,该程序需要正确编程才能学习。幸运的是,这是一个相当有限的逻辑空间,所以它不会像教程序能够看到物体或类似的东西那么复杂。

【讨论】:

不正确,您应该查找图灵机上无法确定的问题。 公平地说,我说如果一个人可以学习正则表达式,那么机器可以。我一般不是这个意思。 @scurial 我不认为有问题被证明可以由人解决但在图灵机上无法确定,是吗?【参考方案4】:

是的,这当然是“可能的”;伪代码如下:

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;

问题是有无数的正则表达式可以匹配示例列表。这段代码提供了集合中最简单/最愚蠢的正则表达式,基本上匹配正面示例列表中的任何内容(没有其他内容,包括任何负面示例)。

我认为真正的挑战是找到与所有示例匹配的最短正则表达式,但即便如此,用户也必须提供非常好的输入以确保生成的表达式是“正确的”。

【讨论】:

当用户输入正和负样本时,它开始变得有趣。正则表达式必须匹配正样本而不匹配负样本。 @blixtor - 实际上,这很容易。只是不要在构造的正则表达式中放入任何负面示例,它们将被拒绝。请记住,代码构建的仅匹配正例;根据定义排除负面示例(以及其他任何内容)! 丹尼尔是对的。如果没有更高级别的描述,则可以从示例列表中一致且准确地推断出备选列表。【参考方案5】:

An Introduction to Computational Learning Theory 这本书包含学习有限自动机的算法。由于每种正则语言都等价于一个有限自动机,因此可以通过程序学习一些正则表达式。 Kearns and Valiant 展示了一些无法学习有限自动机的情况。一个相关的问题是learning hidden Markov Models,它是可以描述字符序列的概率自动机。请注意,编程语言中使用的大多数现代“正则表达式”实际上比正则语言更强大,因此有时更难学习。

【讨论】:

【参考方案6】:

@Yuval 是正确的。您正在研究计算学习理论,或“归纳推理”。

这个问题比你想象的要复杂,因为“学习”的定义并不简单。一个常见的定义是学习者可以随时吐出答案,但最终,它必须要么停止吐出答案,要么总是吐出相同的答案。这假设输入的数量是无限的,并且绝对不会保证程序何时会做出决定。此外,您无法判断它何时做出决定,因为它可能稍后仍会输出不同的内容。

根据这个定义,我很确定常规语言是可以学习的。根据其他定义,没有那么多......

【讨论】:

【参考方案7】:

没有计算机程序能够根据有效匹配列表生成有意义的正则表达式。让我告诉你为什么。

假设您提供示例 111111 和 999999,计算机应生成:

    与这两个示例完全匹配的正则表达式:(111111|999999) 匹配 6 个相同数字 (\d)\15 的正则表达式 匹配6个1和9的正则表达式[19]6 匹配任意 6 位数字的正则表达式 \d6 以上三个中的任何一个,带有单词边界,例如\b\d6\b 前三个中的任何一个,前面或后面都没有数字,例如 (?&lt;!\d)\d6(?!\d)

如您所见,可以通过多种方式将示例泛化为正则表达式。计算机构建可预测的正则表达式的唯一方法是要求您列出所有可能的匹配项。然后它可以生成与这些匹配项完全匹配的搜索模式。

如果您不想列出所有可能的匹配项,则需要更高级别的描述。这正是正则表达式旨在提供的。您只需告诉程序匹配“任何六位数字”,而不是提供一长串 6 位数字。在正则表达式语法中,这变为 \d6。

任何提供与正则表达式一样灵活的高级描述的方法也将与正则表达式一样复杂。像RegexBuddy 这样的所有工具都可以让创建和测试高级描述变得更容易。 RegexBuddy 不是直接使用简洁的正则表达式语法,而是让您能够使用简单的英语构建块。但它无法为您创建高级描述,因为它无法神奇地知道何时应该概括您的示例,何时不应该概括。

当然可以创建一个工具,该工具使用示例文本以及用户提供的指南来生成正则表达式。设计这样一个工具的难点在于它如何向用户询问它需要的指导信息,而不会使工具比正则表达式本身更难学习,并且不将工具限制为常见的正则表达式工作或简单的正则表达式。

【讨论】:

你是对的,我在发布我的问题后发现的许多学习算法都需要正负信息。据我了解,不需要明确的“高级描述”,因为用户是通过回答问题来提供的。 如果一个工具提出问题,那么问题和给出的答案的组合形成更高级别的描述。此类工具的质量很大程度上取决于它提出的问题。 这很愚蠢,因为如果您提供另一个示例,那么您可以排除其中一些可能性。另一个例子排除了更多。 @Cris:无论您提供多少样本,原则仍然存在。它只是改变了可能性。例如,添加 123456 会将 #2 更改为 (\d)\15|123456,将 #3 更改为 [19]6|123456。或者它可以将 #3 更改为 [1-69]6。甚至可能是所需的模式将匹配 6 个相同的数字或 6 个数字,其中每个数字都比前一个数字大 1。即使您提供 10,000 个 6 位数字的样本,如果没有用户的额外说明,程序也无法区分 #1、#4、#5 或 #6。 我觉得这个问题很容易解决如下:程序尽可能地通用(在合理范围内),然后给出它认为匹配的其他示例。通过简单地告诉它“是”和“否”建议的匹配,您可以帮助它了解您实际尝试捕获的内容的范围。我很想在文本编辑器中看到一个工具,它使用这个概念并从当前打开的文件中提出匹配。【参考方案8】:

有一种基于 prolog 的语言专门用于解决此类问题。它叫做progol。

正如其他人所提到的,基本思想是归纳学习,在 AI 圈子中通常称为 ILP (inductive logic programming)。

第二个链接是关于 ILP 的 wiki 文章,如果您有兴趣了解有关该主题的更多信息,其中包含许多有用的源材料。

【讨论】:

【参考方案9】:

我在 Google 和 CiteSeer 上做了一些研究,发现了这些技术/论文:

Language identification in the limit Probably approximately correct learning

Dana Angluin 的“Learning regular sets from queries and counterexamples”看起来很有希望,但我找不到 PS 或 PDF 版本,只有引用和研讨会论文。

在理论上这似乎是一个棘手的问题。

【讨论】:

【参考方案10】:

是的, 有可能的, 我们可以从示例中生成正则表达式(文本 -> 所需的提取)。 这是一个可以完成工作的在线工具:http://regex.inginf.units.it/

Regex Generator++ 在线工具使用 GP 搜索算法从提供的示例生成正则表达式。 GP 算法由多目标适应度驱动,从而导致更高的性能和更简单的解决方案结构(奥卡姆剃刀)。 该工具是的里雅斯特大学 (Università degli studi di Trieste) 机器学习实验室的演示应用程序。 请看视频教程here。

这是一个研究项目,因此您可以阅读有关使用的算法here。

看哪! :-)

当且仅当提供的示例很好地描述了问题时,才有可能从示例中找到有意义的正则表达式/解决方案。 考虑这些描述提取任务的示例,我们正在寻找特定的项目代码;示例是文本/提取对:

"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,这可能是一个重要的证明。

【讨论】:

这应该是最佳答案。这是可能的,这证明了这一点。源代码在这里:github.com/MaLeLabTs/RegexGenerator 您的产品代码示例说明了为什么所说的人应该查找产品代码的规范并根据规范编写正则表达式,而不是试图从一组有限的示例产品中推断出正则表达式代码(无论是人还是程序试图推断正则表达式)。 这是正确的做事方式。我的例子只是从概念上解释问题的一种方式。有时没有规范,或者这个人根本不会自己写正则表达式(缺乏知识)。 为了更准确和明确:-),“这是做事的正确方式” -> “你是对的,你是最好的做事方式,你应该始终从规范开始尽可能” 文章《Inference of Regular Expressions for Text Extraction from Examples》包含算法的详细解释machinelearning.inginf.units.it/publications/…

以上是关于计算机是不是可以通过用户提供的示例“学习”正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章

学习正则表达式笔记

regex正则表达式学习

Twitter用户名的正则表达式

小白的正则表达式学习之旅-01

linux学习-grep使用正则表达式示例

Python学习 :正则表达式