MySQL中点字符的全字匹配
在MySQL中,在只需要“整词匹配”的文本字段中搜索关键字时,可以使用REGEXP和[[::]]词边界标记:MySQL中点字符的全字匹配,mysql,regex,Mysql,Regex,在MySQL中,在只需要“整词匹配”的文本字段中搜索关键字时,可以使用REGEXP和[[::]]词边界标记: SELECT name FROM tbl_name WHERE name REGEXP "[[:<:]]word[[:>:]]" 从tbl_name中选择name,其中name REGEXP“[[::]]” 例如,当我们想要查找包含“europe”的所有文本字段时,使用 从tbl_name中选择name,其中name REGEXP“[[::]]” 将返回“欧洲地图”,但
SELECT name FROM tbl_name WHERE name REGEXP "[[:<:]]word[[:>:]]"
从tbl_name中选择name,其中name REGEXP“[[::]]”
例如,当我们想要查找包含“europe”的所有文本字段时,使用
从tbl_name中选择name,其中name REGEXP“[[::]]”
将返回“欧洲地图”,但不返回“欧盟”
但是,当目标匹配词包含“点字符”(如“u.s.”)时,我应该如何提交正确的查询?我尝试了以下查询,但没有一个看起来正确
一,
从tbl_name中选择name,其中name REGEXP“[[::]]”
二,
从tbl_name中选择name,其中name REGEXP“[[::]]”
三,
从tbl_name中选择name,其中name REGEXP“[[::]]”
当使用双反斜杠转义特殊字符时,正如d'alar'cop所建议的,它返回空字符,即使表中有类似“美国国会”的内容
SELECT name FROM tbl_name WHERE name REGEXP "[[:<:]]u\\.s\\.[[:>:]]"
从tbl_name中选择name,其中name REGEXP“[[::]]”
任何建议都将不胜感激 只需使用此查询:
SELECT name FROM tbl_name WHERE name REGEXP ""[[:<:]]u\\.s\\.([[:blank:]]|$)"
从tbl_name中选择name,其中name REGEXP”“[[:此处的工作示例:
从tbl_name中选择name,其中name REGEXP”[[:谓词的基本问题是
是非单词字符,如果在开始测试之后或结束测试之前,任何非单词字符都会导致单词边界测试失败。您可以看到该行为
使问题进一步复杂化的是,MySQL使用的正则表达式的风格非常有限。根据,MySQL使用的正则表达式与其他风格的正则表达式相比,如果您阅读底部的图表,它的功能非常有限
要解决您的问题,您必须创建一个新的正则表达式来替换单词边界的功能,以便允许非单词字符成为边界的一部分。我提出了以下正则表达式:
(^|[^[:alnum:]_])YOUR_TEXT_HERE($|[^[:alnum:]_])
这相当于下面的标准正则表达式:
(^|[^a-zA-Z0-9_])YOUR_TEXT_HERE($|[^a-zA-Z0-9_])
正则表达式在文本的开始和结束处搜索非单词字符或字符串边界。(^ |[^[^[:alnum:])
匹配字符串的开始、字母数字字符或下划线。结束模式类似,只是它匹配字符串的结束而不是开始
该模式的设计目的是最好地匹配以下词语边界的定义:
[边界]分别匹配单词的开头和结尾。A
word是一个不带或的单词字符序列
后跟单词字符。单词字符是字母数字
类中的字符或下划线
测试结果
使用上面的正则表达式,我提出了一个场景,在这个场景中,我测试了一个在开始和结束处都包含非单词字符的字符串-.u.
。我尝试了一组合理的测试项目。您可以在
测试数据
test string not present: 'no match'
missing .'s: 'no us match'
missing last .: 'no u.s match'
missing first .: 'no us. match'
test start boundary word character: 'no.u.s.match'
test end boundary word character: 'no .u.s.match'
test boundaries word character: 'no.u.s.match'
test basic success case: 'yes .u.s. match'
test start boundary non-word character: 'yes !.u.s. match'
test end boundary non-word character: 'yes .u.s.! match'
test boundaries non-word character: 'yes !.u.s.! match'
test start of line: '.u.s.! yes match'
test end of line: 'yes match .u.s.'
查询
SELECT *
FROM TestRegex
WHERE name REGEXP '(^|[^[:alnum:]_])[.]u[.]s[.]($|[^[:alnum:]_])';
结论
所有阳性病例均返回,阴性病例均未返回=>所有测试病例均成功
- 您可以对句点字符使用
[.]
,而不是\.
,我发现在SQL表达式的上下文中,它更具可读性
- 您可以根据自己的需要将用于定义边界的集合调整为或多或少的限制。例如,您还可以限制一些非单词字符:
[^a-zA-Z_0-9.!?$]
中有一张特殊字符表,以及如何摆脱这些字符
像这样做您的查询
SELECT name FROM tbl_name WHERE name REGEXP "[[:<:]]u[.]s[.][[:>:]]"
从tbl_name中选择name,其中name REGEXP“[[::]]”
或
从tbl_name中选择name,其中name REGEXP“[[::]]”
将起作用此正则表达式满足您的要求:
SELECT name
FROM tbl_name
WHERE name REGEXP '([[:blank:][:punct:]]|^)u[.]s[.]([[:punct:][:blank:]]|$)'
当前面有以下内容时,这与美国相匹配:
- 空白(空格、标签等)
- 标点符号(逗号、括号等)
- 什么都没有
然后是:
- 空白(空格、标签等)
- 标点符号(逗号、括号等)
- 什么都没有
请参阅包含上述各点的边缘案例。是否需要双反斜杠来避免特殊字符?我尝试了anubhava的第二个建议,但结果包含类似“UNS C69100”的内容。至于anubhava的第一个建议,它可能返回类似“u.s.abc”的内容“,这是不受欢迎的。@user1036719:所以你不想要u.s.abc
,但是u.abc
怎么样?你可以试试:”[[:@anubhava:“u.s.abc”是可取的,如果存在的话。虽然链接是一个有用的资源,但这是唯一一个提示[.period.]
,句点不是单词字符,因此在单词结束边界标记之前永远不会匹配。
(^|[^a-zA-Z0-9_])YOUR_TEXT_HERE($|[^a-zA-Z0-9_])
test string not present: 'no match'
missing .'s: 'no us match'
missing last .: 'no u.s match'
missing first .: 'no us. match'
test start boundary word character: 'no.u.s.match'
test end boundary word character: 'no .u.s.match'
test boundaries word character: 'no.u.s.match'
test basic success case: 'yes .u.s. match'
test start boundary non-word character: 'yes !.u.s. match'
test end boundary non-word character: 'yes .u.s.! match'
test boundaries non-word character: 'yes !.u.s.! match'
test start of line: '.u.s.! yes match'
test end of line: 'yes match .u.s.'
SELECT *
FROM TestRegex
WHERE name REGEXP '(^|[^[:alnum:]_])[.]u[.]s[.]($|[^[:alnum:]_])';
SELECT name FROM tbl_name WHERE name REGEXP "[[:<:]]u[.]s[.][[:>:]]"
SELECT name FROM tbl_name WHERE name REGEXP "[[:<:]]u[[.period.]]s[[.period.]][[:>:]]"
SELECT name
FROM tbl_name
WHERE name REGEXP '([[:blank:][:punct:]]|^)u[.]s[.]([[:punct:][:blank:]]|$)'