谓词的基本问题.
是非单词字符,如果它们跟随开始测试或在结束测试之前,任何非单词字符都会导致单词边界测试失败。您可以在此处查看行为。
使问题更加复杂的是,MySQL 使用的正则表达式的风格非常有限。根据Regular-Expressions.info,MySQL 使用POSIX-ERE,如果您阅读底部的图表正则表达式风格比较,与其他风格相比,它的功能很少。
要解决您的问题,您必须创建一个新的正则表达式来替换单词边界的功能,以便允许非单词字符成为边界的一部分。我想出了以下正则表达式:
(^|[^[:alnum:]_])YOUR_TEXT_HERE($|[^[:alnum:]_])
这相当于下面的标准正则表达式:
(^|[^a-zA-Z0-9_])YOUR_TEXT_HERE($|[^a-zA-Z0-9_])
正则表达式在文本的开头和结尾搜索非单词字符或字符串边界。 (^|[^[:alnum:]_])
匹配字符串开头、字母数字字符或下划线。结束模式类似,只是它匹配字符串的结尾而不是开头。
该模式旨在最好地匹配MySQL 手册中正则表达式中单词边界的定义:
[Boundaries] 分别匹配单词的开头和结尾。单词是前面或后面没有单词字符的单词字符序列。单词字符是alnum类中的字母数字字符或下划线。
测试结果
使用上面的正则表达式,我想出了一个场景,我测试一个在开头和结尾包含非单词字符的字符串 - .u.s.
。我试图想出一套合理的测试项目。您可以在
SQLFiddle查看结果。
测试数据
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.!?#$]
.