在下面的查询中,我想找到以 engineer 开头的记录。例如我想回退描述为 engineer ing
的记录SELECT * FROM app.desc_test t
WHERE lower(t.desc) REGEXP '[[:<:]]engineer[[:>:]]';
单词边界可以正确处理所有特殊字符(例如,前后的逗号,空格,特殊字符等),但是我不确定如何编写正则表达式,使其以开头工程师。
此外,我要如何说这句话或以工程师结尾。
CREATE TABLE desc_test ( id int(11) NOT NULL AUTO_INCREMENT, desc varchar(1000) COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
修改
该值是未知的/动态的,因此硬编码任何“ ing” 表达式都不是解决方案。
答案 0 :(得分:2)
如果只想匹配单词的开头,则只需从正则表达式中删除# Play an audio beep. Any audio URL will do.
from google.colab import output
output.eval_js('new Audio("https://upload.wikimedia.org/wikipedia/commons/0/05/Beep-09.ogg").play()')
。
[[:>:]]
答案 1 :(得分:1)
注意:首选Bill Karwin引用的全文搜索
因为使用REGEXP比索引解决方案要慢数千倍
要使用当前的REGEXP实现,您的MySQL应该如下所示:
SELECT * FROM app.desc_test t WHERE lower(t.desc)
REGEXP '[[:<:]]engineer[a-z]*[[:>:]]';
正则表达式如下:
[[:<:]]engineer[a-z]*[[:>:]]
含义:
[[:<:]]
-单词边界的开头
engineer
-搜索(动态)给出的字符串
[a-z]
-介于a到z之间的任意字符,介于0到任意次数之间。
*
-上面的“组”在零到任意次数之间。
[[:>:]]
-单词边界的结尾
以上内容应满足您的需求。您还可以对其进行自定义,例如包含数字((a-z0-9)
)或任何您想要的内容。
一个:
修订,改进:使用[[:alpha:]]
,这样:
[[:<:]]engineer[[:alpha:]]*[[:>:]]
两个:
正确的pointed out by Barmar实际上几乎不需要多余的REGEXP。您的语言界限,或缺乏界限,会为您效劳。
因此,要选择以engineer
开头或以engineer
结尾的任何单词,只需简单地执行REGEXP OR 语句:
SELECT * FROM app.desc_test t WHERE lower(t.desc)
REGEXP '([[:<:]]engineer)|(engineer)[[:>:]])'
这意味着:
在以下情况下返回true:
这应该完全符合您的需求。已在MySQL 5.7上进行了测试。
来源:
示例案例:
Engineer
匹配
Engineering
匹配
Engineers
匹配
Engineer!
匹配
此外,我要如何说这句话或以工程师结尾。
只需翻转REGEXP并将其设置为 OR 语句:
SELECT * FROM app.desc_test t WHERE lower(t.desc)
REGEXP '[[:<:]](engineer[[:alpha:]]*)|([[:alpha:]]*engineer)[[:>:]]';
告诉REGEXP:
“在单词的开头查找工程师,然后输入任何az值,或者在末尾查找工程师的任何az值“
答案 2 :(得分:1)
对于“ desc开头”:
“开头为:
REGEXP: '^engineer...'
LIKE: 'engineer%...'
案例折叠:
If the collation of the column is `..._ci`, then do _not_ waste time with `LOWER()`.
因此,这对于查找以开头“ engineer”或“ engineering”或“ Engineer”等的desc
是最佳的:
WHERE t.desc LIKE 'engineer%'
如果您的意思是“ desc 包含“工程师”或...的地方”,那么
WHERE t.desc REGEXP '[[:<:]]engineer'
但是更好的方法是使用FULLTEXT(desc)
并使用它;它允许单词在desc
中的任何位置,而desc
可以为TEXT
。
WHERE MATCH(desc) AGAINST('+engineer*' IN BOOLEAN MODE)
您必须根据实际需求选择选项。同时,这是它们的相对性能:
LOWER(desc) ...
–较差,无论条款的其余部分如何LIKE 'engineer%'
-如果您有INDEX(desc)
LIKE 'engineer%'
-较差,没有索引或带有前缀:INDEX(desc(100))
MATCH...
-出色的索引FULLTEXT
。REGEXP ...
-贫穷;将检查每条记录对于“有一个以或开头的单词”:
您需要列出正面和负面的测试用例:
engineering blah
The engineer.
MechanicalEngineering -- neither starts nor ends at word boundary??
engineer
如果所有这些都有效,那么这是唯一可行的答案:
WHERE t.desc LIKE '%engineer%'
等效的REGEXP 'engineer'
速度较慢(但效果相同)。
对于其他情况,我会看一些接近的东西
WHERE t.desc REGEXP '[[:<:]]engineer|engineer[[:>:]]'
查找以“ engineer”开头或结尾的“单词”。请注意,这不包括“ MechanicalEngineering”。