java - 生成正则表达式以匹配列表 A 中的字符串,但不匹配列表 B 中的字符串

标签 java regex string algorithm text

<分区>

Possible Duplicate:
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}.+$/

最后一个例子

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

理想的表达方式与平凡的解决方案相同

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

此外,我并不是在寻找理想的解决方案,任何比琐碎的问题都更好的解决方案都会有所帮助。我一直在思考生成简单解决方案列表的思路,然后尝试合并公共(public)子字符串,同时注意我们不会漫游到 ListB 领域。

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

最佳答案

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

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

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

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

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

关于java - 生成正则表达式以匹配列表 A 中的字符串,但不匹配列表 B 中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12887069/

相关文章:

java - Head、Option、Trace http 方法与 Servlet 的使用和实现

java - 如何处理这个类的可见性问题?

regex - 如何从 Perl 正则表达式生成所有可能的排列?

Python 按层次结构后的多个分隔符拆分字符串

java - 列表数组错误?

c# - C#中如何获取字符的ASCII值

java - 避免在 Java 8 stream reduce 方法中使用全局变量

java - 我如何估计一个类的总 permgen 内存消耗?

java - [...] 正则表达式的含义是什么?

PHP RegEx 删除字符串中每个逗号后的空格