【问题标题】:how to determine the sub string in a regular expression?如何确定正则表达式中的子字符串?
【发布时间】:2014-09-24 10:00:42
【问题描述】:

我已经实现了一个用于模式搜索的 trie,并且运行良好。使用这个 trie,我可以找到 O(n) 复杂度的文本中存在的所有关键字。

问题是我想为我的模式(关键字)使用正则表达式,并希望找到文本中存在的所有关键字。

示例: 我写 [a-z0-9\.]{6, 30}\@[a-z0-9\.]{2,12}\.[a-z0-9]{2,6} 查找电子邮件 ID,它会为我获取正确的内容,但它不会找到位于第一个或第二个块下的子字符串。

例如,我将文本设置为。 examplegmail@gmail.com

关键字是:ample mail

在本例中,此正则表达式将告诉我电子邮件 ID 的结束位置,但不会告诉我有关 amplemail 关键字的任何信息。

编辑:假设我的正则表达式为 a*(b|cd?)+ DFA 看起来像::

现在我在这个数据中有像 dfdfdacbcbbcb 这样的数据,它会告诉我到达 ac 后每个字符的模式等等,但是我应该如何到达知道结束模式的长度????

【问题讨论】:

  • 你使用什么语言?
  • 基本上我使用的是 C,但我不要求使用正则表达式库。我正在创建一个 trie,基于将它们视为关键字的正则表达式...

标签: regex string algorithm pattern-matching trie


【解决方案1】:

你的“trie”包含操作:“test for char”“branch to nth subtree”。

添加另一个运算符来保存位置:“记住第 N 个字符索引”,它将 trie 正在检查的当前字符位置写入到字符串的指针数组的第 n 个槽中。

在您的(抽象)trie 规范中插入这些运算符,编译为真正的 trie,然后运行它。当 trie 匹配器“跨越”匹配中的各个关键点时,它可以将这些点记录在字符串缓冲区中。在最后一场比赛中,您有一个指向比赛子部分的指针数组(任意数量)。

你的例子:

[a-z0-9\.]{6, 30}\@[a-z0-9\.]{2,12}\.[a-z0-9]{2,6} 

假设我想选择@左右两边的文本。

我添加了位置保存操作符,我已经任意表示为“#n”:

#1[a-z0-9\.]{6, 30}#2\@[a-z0-9\.]{2,12}\.[a-z0-9]{2,6}#3

这将(相当简单)捕获起始位置,即“@”的位置 符号,和(相当琐碎)结束位置,如位置 1、2 和 3。当然,如果你认为合适,你可以在中间更多。

[许多正则表达式系统在遇到分组运算符 (...) 时会隐式执行此操作,从左到右对分组进行编号。这总是足够的,因为您总是可以在这样的分组运算符中包装一个有趣的子正则表达式。我喜欢明确的指示方案;读者和模式匹配器很清楚,它必须在哪里插入这些位置捕获操作。我们已经使用上面的 #n 符号实现了正则表达式匹配器。]。

如果您正在寻找各种各样的关键字和相关文本,那么您的 trie 中可能有很多选择运算符。您可以在每个选择分支的适当位置添加这些位置捕获运算符,以挑选出与关键字相关的信息。您可能需要添加另一个运算符“已识别关键字 k”,以帮助解释模式匹配器结果的代码了解找到了哪些特殊关键字,从而了解如何解释位置索引。

【讨论】:

  • 感谢您的回复,但我不明白我在想什么。请查看编辑并尝试澄清我的疑问。我会很感激的。
  • 你不应该改变你问题的本质(“我有一个尝试......”)然后抱怨有人投入时间和精力的答案。然而答案还是一样的;您需要指明您想在比赛中的哪个位置获取位置信息。如果您构建一个高效的匹配自动机,如您现在所展示的,您需要在您需要知道它的状态中使用“保存我的位置”操作来装饰它的状态。如果您的模式是“a*#1(b|cd?)+#2”,您将修改 state1 和 state4 以记住指向字符源的指针....
  • 为此构建 DFA 需要您调整其构建的标准算法。留给读者作为练习。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-21
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多