如何使用正则表达式完全匹配MySQL中的记录?

时间:2011-10-15 22:23:23

标签: php mysql regex

我正在制作一个新闻系统,使用独特的slu to来识别文章。在创建新文章时,我需要确保该独特的slug尚未使用。因此,如果两篇文章具有完全相同的名称,则它们将生成完全相同的slug。我希望在它正在使用的情况下在slug的末尾添加一个数字。

像这样:

  • 一些,真的,有趣,文章
  • 一些,真的,有趣,文章-1
  • 一些,真的,有趣,文章-2

等等。因此,在我的测试用例中,我选择的数据库中的所有记录都与“一些非常有趣的文章”完全匹配,并带有0或更多“-number”。因此,在这种情况下,我将返回3行,因此下一个slug将是“some-really-interesting-article-3”。

这很有效,除了我的正则表达式表现特殊(或者可能非常正常,我只是吮吸正则表达式)并且还返回具有部分匹配的行。因此,如果我搜索“有些非常有趣”,那就会过去。

SELECT id, title, slug
FROM news 
WHERE slug RLIKE '([[:<:]]some-really-interesting-article[[:>:]][-\d]*)'

正如我所说的,如果我用“some-really-interesting”运行上面的正则表达式,它将返回所有3行。

请告诉我,我公然无知地做错了。感谢。

3 个答案:

答案 0 :(得分:1)

尝试

WHERE slug RLIKE '(^some-really-interesting-article(-[0-9]+)?$)'

答案 1 :(得分:1)

这个怎么样?

"^some-really-interesting-article(-[[:digit:]]+)?$"

希望这会奏效:)

答案 2 :(得分:0)

正如其他人已经指出的那样,这将有效:

SELECT id, title, slug FROM news
WHERE slug RLIKE '^some-really-interesting-article(-[0-9]+)?$'

然而,MySQL不够聪明,无法充分利用RLIKE的索引。 (如果slug列上有索引,它可能会尝试使用它,但必须进行完整的索引扫描。)但事实证明,您可以使用冗余LIKE帮助MySQL更有效地处理查询的条件,如下所示:

SELECT id, title, slug FROM news
WHERE slug LIKE 'some-really-interesting-article%'
  AND slug RLIKE '^some-really-interesting-article(-[0-9]+)?$'

LIKE查询可能会匹配某些误报,例如some-really-interesting-article-about-something-else-entirely,但RLIKE会将它们排除在外。当然,如果你不关心这些误报,你可以完全忽略RLIKE

当然,另一种可能性是在slug列上创建一个唯一索引(无论如何你应该拥有它)并且只是继续增加slug并尝试插入记录直到INSERT成功。当然,这也意味着你应该检查错误代码和消息,看看它失败的原因。 (如果INSERT由于重复值而失败,则error code应为1062error message应包含重复键的名称。)

无论如何,here an SQLize link如果你想玩查询;我留下了一些评论。