查询sqlite到LIKE但整个单词

时间:2013-05-08 21:31:57

标签: python sql sqlite

我有两张桌子:     TableA:id,StringA     TableB:id,StringB

从TableA中获取所有行后,我希望匹配尽可能接近TableB中的单词。我正在尝试做这样的事情:

c.execute('SELECT id, StringB FROM TableB WHERE StringB LIKE "'+stringa+'%" COLLATE NOCASE')
foundrows=c.fetchall()
if (len(foundrows)>0):
    print 'Hmm. Which one...'
    for foundrow in foundrows:    
        print 'looking for:'+stringa+'  found:'+ foundrow[1]

这给了我类似的东西:

Hmm. Which one...
looking for:goo  found:good
looking for:goo  found:good 1
looking for:goo  found:good 2
looking for:goo  found:good 1 dk
looking for:goo  found:good 2 dk
looking for:goo  found:Good Friday
looking for:goo  found:goose
looking for:goo  found:Good Friday 1
looking for:goo  found:good sport
looking for:goo  found:good job
looking for:goo  found:good morning
looking for:goo  found:good night
looking for:goo  found:goodbye 1
looking for:goo  found:goodbye e
looking for:goo  found:goodbye

我真正想要的是'SELECT id,StringB FROM TableB WHERE StringB CONTAINS WORD“'+ stringa +'”

实现“包含Word”的最佳方式是什么?

4 个答案:

答案 0 :(得分:7)

构建一个这样的where子句:

where (' ' || StringB || ' ') LIKE '% stringa %'

StringB周围的空格可确保您在字符串的开头和结尾处捕获单词。

答案 1 :(得分:2)

您可以定义REGEXP函数:

import sqlite3
import re
def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

conn = sqlite3.connect(':memory:')
conn.create_function("REGEXP", 2, regexp)
cursor = conn.cursor()
cursor.execute('CREATE TABLE foo (bar TEXT)')
cursor.executemany(
    'INSERT INTO foo (bar) VALUES (?)', [
        ('this is not good', ),
        ('world of goo', ),
        ('goo: the final frontier', ),
        ('goo',)])
cursor.execute('SELECT bar FROM foo WHERE bar REGEXP ?', [r'\bgoo\b'])
# cursor.execute('SELECT bar FROM foo WHERE (" " || bar || " ") LIKE ?', ["% goo %"])
data = cursor.fetchall()
print(data)

产量

[(u'world of goo',), (u'goo: the final frontier',), (u'goo',)]

另请注意,正则表达式\bgoo\b将匹配非空格的字边界。例如,如果您的表值为goo:,则\bgoo\b会匹配,但" " || bar || " " LIKE "% goo %"则不会。


在执行sqlite查询时获得正则表达式的强大功能可能会很好,但它可能不是很快,因为它需要在表中的每个项目上调用Python函数。

假设您搜索的单词没有标点符号或空格以外的其他单词边界,Blorgbeard的方法可能更快。

答案 2 :(得分:0)

你可以这样做;

WHERE StringB LIKE "%'+stringa+'%"

答案 3 :(得分:0)

您可以使用glob函数(或运算符)进行区分大小写的比较。来自D. Richard Hipp的SQLite用户邮件列表:

  

LIKE不区分大小写,并使用通配符'%'和'_'

     

GLOB区分大小写并使用通配符'*'和'?'。

     

GLOB还允许你说'[abcd]'表示集合中的任何字符   “ABCD”。

     

LIKE可以有一个ESCAPE字符选项来转义通配符。 GLOB   不能。但是如果你想匹配一个通配符你可以使用GLOB   使用'[*]'或'[?]'。

     

除此之外,它们是相同的。实际上,GLOB和LIKE已经实现   使用相同的子程序,用不同的参数调用来确定   通配符和区分大小写。

如果你真的想要匹配整个单词,你需要进行多次测试。例如,

WHERE glob(StringB + ' *',        StringA)
   OR glob('* ' + StringB,        StringA)
   OR glob('* ' + StringB + ' *', StringA)

分别在StringA的开头,结尾和中间捕捉单词。或者以Blorgbeard的回应为基础

WHERE glob(' '+StringB+' ','* '+StringA+' *')