我有这个正则表达式:
"(WORD1.*WORD2.*WORD3)|(WORD1.*WORD3.*WORD2)|(WORD2.*WORD1.*WORD3)|(WORD2.*WORD3.*WORD1)|(WORD3.*WORD1.*WORD2)|(WORD3.*WORD2.*WORD1)"
它与这些词匹配:
WORD1WORD2WORD3 WORD1AWORD2BWORD3C WORD3WORD1WORD2 WORD1WORD2WORD3WORD1
但不是这些话:
WORD1WORD1WORD2 WORD1AWORD1BWORD2C
当该正则表达式找到包含任意顺序的 3 个单词(WORD1
、WORD2
、WORD3
)的字符串时,它就会匹配。
我想用更多的单词做同样的事情,但问题是正则表达式的大小随着单词的数量呈指数增长。 是否可以简化此正则表达式的构造方式来解决此问题(大小不会呈指数增长)?
简单地迭代所有字符串并过滤掉所有不包含所有关键字的字符串:
(可以在下面的代码片段中找到更简洁的版本)
尝试一下:
您可以对每个单词使用正向前瞻。
下面的更高性能版本指定起始锚点,并且在验证前瞻后仅匹配单个字符。根据OP的要求,此技术仅适用于
matching
,而不适用于extraction
。正向先行就像一个门,只有当括号内指定的匹配存在时,它才会继续,但它不会消耗或捕获它匹配的内容——它总是零长度。如果您“向前看”以查看每个单词前面是否存在
.*
,那么这些单词的顺序并不重要。如果每个单词为真,则继续进行,而不会使用任何内容进行匹配。 p>如果您只关心内容是否匹配,那么两个表达式之间唯一的实质性区别就是它们花费的时间。假设您的内容中只有 3 个必需单词中的 2 个。除非解释表达式的软件能够识别尝试是徒劳的,否则它可能会在第一个位置查找三个单词“失败”,然后在第二个位置尝试“失败”,等等,直到到达最后一个位置才放弃。通过指定
^
,只会在第一个位置进行检查,节省了其他不必要检查的时间。当您只是寻找内容中是否存在所有单词的真/假答案时,从末尾删除*
可以防止一些不必要的捕获。