20

我正在尝试将一些全词表达式与 MySQL REGEXP 函数匹配。当涉及双引号时,就会出现问题。

MySQL 文档说:“要在正则表达式中使用特殊字符的文字实例,请在其前面加上两个反斜杠 () 字符。”

但是这些查询都返回 0:

SELECT '"word"' REGEXP '[[:<:]]"word"[[:>:]]';             -> 0
SELECT '"word"' REGEXP '[[:<:]]\"word\"[[:>:]]';           -> 0
SELECT '"word"' REGEXP '[[:<:]]\\"word\\"[[:>:]]';         -> 0
SELECT '"word"' REGEXP '[[:<:]] word [[:>:]]';             -> 0
SELECT '"word"' REGEXP '[[:<:]][[.".]]word[[.".]][[:>:]]'; -> 0

我还能尝试什么来获得 1?或者这是不可能的?

4

4 回答 4

32

让我先引用文档

[[:<:]], [[:>:]]

这些标记代表单词边界。它们分别匹配单词的开头和结尾。单词是前面或后面没有单词字符的单词字符序列。单词字符是 alnum 类中的字母数字字符或下划线 (_)。

从文档中我们可以看到您的问题背后的原因,它不是由任何转义引起的。问题是您试图[[:<:]]在字符串的开头匹配单词边界,这是行不通的,因为从文档中可以看到单词边界将单词字符与非单词字符分开,但在您的情况下第一个字符是 a ",它不是单词字符,因此没有单词边界,最后一个"and 也是如此[[:>:]]

为了使它起作用,您需要将表达式更改为以下表达式:

"[[:<:]]word[[:>:]]"
 ^^^^^^^    ^^^^^^^

请注意单词边界如何将非单词字符与开头"的单词字符和字符串末尾的单词字符分开。w"d

编辑:如果您总是想在字符串的开头和结尾使用单词边界而不知道是否会有实际边界,那么您可以使用以下表达式:

([[:<:]]|^)"word"([[:>:]]|$)

这将匹配开头或字符串开头的单词边界,并且匹配单词边界或字符串^结尾的结尾。我真的建议你研究你试图匹配的数据并寻找常见的模式,如果它们不是适合这项工作的工具,就不要使用正则表达式。

SQL 小提琴演示

于 2013-09-19T18:41:41.337 回答
7

在 MySQL 8.0.4 以上使用:\\bword\\b

参考。https://dev.mysql.com/doc/refman/8.0/en/regexp.html#regexp-compatibility

于 2019-11-14T10:10:55.613 回答
4

在 MySQL 8 及更高版本中

添加到 Oleksiy Muzalyev 的答案

https://dev.mysql.com/doc/refman/8.0/en/regexp.html#regexp-compatibility

在 MySQL 8.04 及更高版本中,您必须使用:

\bword\b

其中\b表示单词边界的 ICU 变体。之前的 Spencer 库使用[[:<:]]来表示单词边界。

当实际使用它作为查询的一部分时,我不得不转义转义字符\,所以我的查询实际上看起来像

SELECT * FROM table WHERE field RLIKE '\\bterm\\b'

从 PHP 查询时,使用引号做同样的事情

$sql = 'SELECT * FROM table WHERE field RLIKE ?';
$args = ['\\bterm\\b'];
...
于 2020-02-06T23:18:26.397 回答
2

你需要更复杂一点:

SELECT '"word"' REGEXP '"word"';                                      --> 1
SELECT '"This is" what I need' REGEXP '"This is" what I need[[:>:]]'; --> 1

那是,

如果测试字符串以“字母”开头/结尾,则在字符串之前/之后使用[[:<:]]/ [[:>:]]

这与盲目地将它们固定在弦上相反。毕竟,您已经在检查搜索字符串中是否有特殊的正则表达式字符来转义它们。这只是这方面的另一项任务。“字母”的定义应与字边界标记所查找的任何内容相匹配。

于 2018-11-01T17:40:36.837 回答