如何在PostgreSQL中获取字符串中regexp匹配的位置?
发布时间:2020-12-13 18:05:30 所属栏目:百科 来源:网络整理
导读:我有一个带书名的表格,我想选择标题与正则表达式匹配的书籍,并按标题中正则表达式匹配的位置排序结果. 单词搜索很容易.例如. TABLE bookid title1 The Sun2 The Dead Sun3 Sun Kissed 在将查询发送到DB之前,我将把.*放在客户端搜索词中的单词之间,所以我在这
我有一个带书名的表格,我想选择标题与正则表达式匹配的书籍,并按标题中正则表达式匹配的位置排序结果.
单词搜索很容易.例如. TABLE book id title 1 The Sun 2 The Dead Sun 3 Sun Kissed 在将查询发送到DB之前,我将把.*放在客户端搜索词中的单词之间,所以我在这里用准备好的regexp编写SQL. SELECT book.id,book.title FROM book WHERE book.title ~* '.*sun.*' ORDER BY COALESCE(NULLIF(position('sun' in book.title),0),999999) ASC; RESULT id title 3 Sun Kissed 1 The Sun 2 The Dead Sun 但是如果搜索词有多个单词,我想匹配标题,这些标题包含搜索词中的所有单词和它们之间的任何内容,并按照之前的位置排序,所以我需要一个返回正则表达式位置的函数,我没有在PostgreSQL官方文档中找到合适的一个. TABLE books id title 4 Deep Space Endeavor 5 Star Trek: Deep Space Nine: The Never Ending Sacrifice 6 Deep Black: Space Espionage and National Security SELECT book.id,book.title FROM book WHERE book.title ~* '.*deep.*space.*' ORDER BY ???REGEXP_POSITION_FUNCTION???('.*deep.*space.*' in book.title); DESIRED RESULT id title 4 Deep Space Endeavor 6 Deep Black: Space Espionage and National Security 5 Star Trek: Deep Space Nine: The Never Ending Sacrifice 我没有找到类似于??? REGEXP_POSITION_FUNCTION的任何功能???,你有什么想法吗?
执行此操作的一种方法(很多):从匹配开始删除字符串的其余部分并测量截断字符串的长度:
SELECT id,title FROM book WHERE title ILIKE '%deep%space%' ORDER BY length(regexp_replace(title,'deep.*space.*','','i')); 在WHERE子句中使用ILIKE,因为这通常更快(并且在这里也一样). 备择方案 根据评论中的要求. SELECT id,title,substring(title FROM '(?i)(^.*)deep.*space.*') AS sub1,length(substring(title FROM '(?i)(^.*)deep.*space.*')) AS pos1,substring(title FROM '(?i)^.*(?=deep.*space.*)') AS sub2,length(substring(title FROM '(?i)^.*(?=deep.*space.*)')) AS pos2,substring(title FROM '(?i)^.*(deep.*space.*)') AS sub3,position((substring(title FROM '(?i)^.*(deep.*space.*)')) IN title) AS p3,regexp_replace(title,'i') AS reg4,length(regexp_replace(title,'i')) AS pos4 FROM book ORDER BY title ILIKE '%deep%space%' DESC NULLS LAST,'i')); 您可以在手册here和here中找到上述所有文档. -> SQLfiddle展示全部. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |