【问题标题】:Generate regular expression to match strings from the list A, but not from list B [duplicate]生成正则表达式以匹配列表 A 中的字符串,但不匹配列表 B [重复]
【发布时间】:2012-10-14 22:13:37
【问题描述】:

可能重复:
How to auto generate regex from given list of strings?

我有两个字符串列表 ListAListB。我需要生成一个正则表达式,它将匹配 ListA 中的所有字符串,并且不会匹配 ListB 中的任何字符串。

  • 字符串可以包含字符、数字和标点符号的任意组合。
  • 如果字符串出现在 ListA 中,则保证它不会出现在 ListB 中。
  • 如果一个字符串不在这两个列表中,我不在乎匹配的结果应该是什么。

列表通常包含数千个字符串,并且字符串彼此非常相似。

我知道这个问题的简单答案,就是生成(Str1)|(Str2)|(Str3) 形式的正则表达式,其中StrN 是ListA 中的字符串。但我正在寻找一种更有效的方法来做到这一点。

理想的解决方案是某种工具,它会接受两个列表并为此生成一个 Java 正则表达式。

更新 1:“高效”是指生成比普通解决方案更短的表达式。理想的算法将生成缩短的可能表达式。以下是一些示例。

ListA = { C10 , C15, C195 }
ListB = { Bob, Billy }

理想的表达方式是

/^C1.+$/

另一个例子,注意ListB的第三个元素

ListA = { C10 , C15, C195 }
ListB = { Bob, Billy, C25 }

理想的表达方式是

/^C[^2]{1}.+$/

最后一个例子

列表A = { A , D ,E , F , H } ListB = { B , C , G , I }

理想表达式与平凡解相同

/^(A|D|E|F|H)$/

另外,我不是在寻找理想的解决方案,任何比琐碎更好的事情都会有所帮助。我正在考虑生成简单解决方案列表,然后尝试合并公共子字符串,同时注意我们不会进入 ListB 领域。

**更新 2*:我并不特别担心生成 RegEx 所需的时间,现代机器上 10 分钟以内的任何内容都是可以接受的

【问题讨论】:

  • 为什么需要是正则表达式?如果您想要性能匹配测试,请使用trie
  • 你确定这可以只使用正则表达式来完成吗?在我看来,它需要一个算法。这也需要更多解释:" ...一个正则表达式,它将匹配 ListA 中的所有字符串,但不会匹配 ListB 中的任何字符串..."
  • 我同意 Bergi 的观点——正则表达式似乎是错误的工具。
  • ListB 需要什么?如果表达式只匹配 ListA 中的字符串(保证不在 B 中),为什么还需要额外检查 ListB?
  • @Vlad,您不必担心诸如分解常见前缀之类的事情。正则表达式库在将正则表达式编译到有限状态机时会执行此操作。

标签: java regex string algorithm text


【解决方案1】:

如果保证两个列表中都没有字符串,并且您不关心两个列表中的字符串,那么您只需要匹配 ListA 中的字符串;您可以完全忽略 ListB。

您提到的“微不足道的答案”是一个完全合理的解决方案。当您说您想要一种“更有效”的方式时,您是指一种生成正则表达式本身的有效方式,还是一种生成更有效地匹配字符串的正则表达式的方式?

  • 如果您想高效地生成正则表达式,大多数语言的字符串工具都提供了一种将字符串列表与分隔符字符串(例如逗号)连接起来以生成单个字符串的方法。没有比这更高效的了。
  • 如果您希望表达式有效地匹配事物,请确保在使用之前“编译”它。 (大多数正则表达式库都有此功能。)编译正则表达式意味着生成正则表达式库实际用于匹配操作的finite-state machine。任何不错的正则表达式库都应该在优化 FSM 方面做得不错,例如尽可能将公共子字符串映射到相同的 FSM 状态。

或者,您可以完全放弃正则表达式,只遍历 ListA 并将其每个字符串与候选字符串进行比较。在这种情况下,单独的比较可能会更快,因为寻找精确的字符串匹配可以比较 4 或 8 字节块中的字符串,而正则表达式必须单独查看每个字符。但是,如果您有很多要比较的字符串,您将在内存中多次遍历候选字符串。反之,正则表达式可以遍历候选字符串一次以找出它是否匹配。

尝试这两种方法。看看哪个更快。

【讨论】:

  • 让正则表达式编译器进行优化”是个好主意 - 只需传入简单的正则表达式即可。当然,这取决于环境,我们需要来自@Vlad 的更多信息。
  • 这不起作用,编译不会简化,事实上,如果它定义得足够普遍(kolmogorov),这通常是一个 NP 完全问题,并且为了得到什么而正确定义肯定不是微不足道的你想,看看MDL(最小描述长度)原则。
猜你喜欢
  • 1970-01-01
  • 2019-04-04
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多