我正在使用正则表达式来获取一组完成下一个语法的单词:
SELECT * FROM words WHERE word REGEXP '^[dcqaahii]{5}$'
我的第一印象让我觉得这很好,直到我意识到有些字母的使用超过了正则表达式中包含的内容。
问题是我想得到所有可以用括号内的字母组成的单词(即5个字母),所以如果我有两个'a',结果单词可以没有'a',一个'a'甚至两个'a',但没有更多。
我应该在我的正则表达式中添加什么来避免这种情况?
提前致谢。
正如其他人所建议的那样,首先检索所有候选人并进行后处理可能会更好:
SELECT * FROM words WHERE word REGEXP '^[dcqahi]{5}$'
但是,没有什么能阻止您执行多个 REGEXP。您可以使用这个邋遢的表达式选择字母“a”的 0、1 或 2 次出现:
'^[^a]*a?[^a]*a?[^a]*$'
所以先进行预过滤,然后将其他 REGEXP 要求与 AND 结合起来:
SELECT * FROM words
WHERE word REGEXP '^[dcqahi]{5}$'
AND word REGEXP '^[^a]*a?[^a]*a?[^a]*$'
AND word REGEXP '^[^i]*i?[^i]*i?[^i]*$'
[编辑]作为事后的想法,我推断对于非元音,您也希望限制为 0 或 1 次出现。既然如此,那你就继续……
AND word REGEXP '^[^d]*d?[^d]*$'
AND word REGEXP '^[^c]*c?[^c]*$'
AND word REGEXP '^[^q]*q?[^q]*$'
AND word REGEXP '^[^h]*h?[^h]*$'
呸。
我能想到的唯一解决方案是使用上面的 SQL,您必须获得一组初始过滤的数据,然后循环遍历它并使用一些更适合做那种的服务器端代码(PHP 等)进一步过滤逻辑。
在正则表达式中,方括号 [] 只是一个字符类,就像一个允许的字符列表。因此,在括号内两次指定相同的字母是多余的。
例如,模式[sed]
将匹配sed
,并且seed
因为e
是允许字符的一部分。之后在大括号 {} 中指定字符数仅仅是字符类先前允许的字符总数。
因此,该模式[sed]{3}
将匹配sed
但不匹配seed
。
我建议将用于测试单词有效性的逻辑从 SQL 转移到您的程序中。